Add @RequestBody tests
This commit is contained in:
@@ -124,15 +124,13 @@ public class RequestBodyArgumentResolver implements HandlerMethodArgumentResolve
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Object> resolveArgument(MethodParameter parameter, ModelMap model,
|
||||
ServerWebExchange exchange) {
|
||||
|
||||
ResolvableType type = ResolvableType.forMethodParameter(parameter);
|
||||
public Mono<Object> resolveArgument(MethodParameter parameter, ModelMap model, ServerWebExchange exchange) {
|
||||
|
||||
TypeDescriptor typeDescriptor = new TypeDescriptor(parameter);
|
||||
boolean convertFromMono = getConversionService().canConvert(MONO_TYPE, typeDescriptor);
|
||||
boolean convertFromFlux = getConversionService().canConvert(FLUX_TYPE, typeDescriptor);
|
||||
|
||||
ResolvableType type = ResolvableType.forMethodParameter(parameter);
|
||||
ResolvableType elementType = convertFromMono || convertFromFlux ? type.getGeneric(0) : type;
|
||||
|
||||
ServerHttpRequest request = exchange.getRequest();
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.web.reactive.result.method.annotation;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URI;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
@@ -29,6 +31,7 @@ import java.util.concurrent.CompletableFuture;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
@@ -120,6 +123,17 @@ public class RequestBodyArgumentResolverTests {
|
||||
.assertError(UnsupportedMediaTypeStatusException.class);
|
||||
}
|
||||
|
||||
@Test // SPR-9942
|
||||
public void missingContent() throws Exception {
|
||||
this.request.writeWith(Flux.empty());
|
||||
ResolvableType type = forClassWithGenerics(Mono.class, TestBean.class);
|
||||
MethodParameter param = this.testMethod.resolveParam(type);
|
||||
Mono<Object> result = this.resolver.resolveArgument(param, new ExtendedModelMap(), this.exchange);
|
||||
|
||||
TestSubscriber.subscribe(result)
|
||||
.assertError(UnsupportedMediaTypeStatusException.class);
|
||||
}
|
||||
|
||||
@Test @SuppressWarnings("unchecked")
|
||||
public void monoTestBean() throws Exception {
|
||||
String body = "{\"bar\":\"b1\",\"foo\":\"f1\"}";
|
||||
@@ -205,6 +219,17 @@ public class RequestBodyArgumentResolverTests {
|
||||
assertEquals(Arrays.asList(new TestBean("f1", "b1"), new TestBean("f2", "b2")), list);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void monoList() throws Exception {
|
||||
String body = "[{\"bar\":\"b1\",\"foo\":\"f1\"},{\"bar\":\"b2\",\"foo\":\"f2\"}]";
|
||||
ResolvableType type = forClassWithGenerics(Mono.class, forClassWithGenerics(List.class, TestBean.class));
|
||||
MethodParameter param = this.testMethod.resolveParam(type);
|
||||
Mono<?> mono = resolveValue(param, Mono.class, body);
|
||||
|
||||
List<?> list = (List<?>) mono.block(Duration.ofSeconds(5));
|
||||
assertEquals(Arrays.asList(new TestBean("f1", "b1"), new TestBean("f2", "b2")), list);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void array() throws Exception {
|
||||
String body = "[{\"bar\":\"b1\",\"foo\":\"f1\"},{\"bar\":\"b2\",\"foo\":\"f2\"}]";
|
||||
@@ -239,6 +264,17 @@ public class RequestBodyArgumentResolverTests {
|
||||
.assertError(ServerWebInputException.class);
|
||||
}
|
||||
|
||||
@Test // SPR-9964
|
||||
@Ignore
|
||||
public void parameterizedMethodArgument() throws Exception {
|
||||
Class<?> clazz = ConcreteParameterizedController.class;
|
||||
MethodParameter param = ResolvableMethod.on(clazz).name("handleDto").resolveParam();
|
||||
SimpleBean simpleBean = resolveValue(param, SimpleBean.class, "{\"name\" : \"Jad\"}");
|
||||
|
||||
assertEquals("Jad", simpleBean.getName());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T resolveValue(MethodParameter param, Class<T> valueType, String body) {
|
||||
@@ -250,7 +286,7 @@ public class RequestBodyArgumentResolverTests {
|
||||
Object value = result.block(Duration.ofSeconds(5));
|
||||
|
||||
assertNotNull(value);
|
||||
assertTrue("Actual type: " + value.getClass(), valueType.isAssignableFrom(value.getClass()));
|
||||
assertTrue("Unexpected return value type: " + value, valueType.isAssignableFrom(value.getClass()));
|
||||
|
||||
return (T) value;
|
||||
}
|
||||
@@ -285,6 +321,7 @@ public class RequestBodyArgumentResolverTests {
|
||||
@RequestBody TestBean testBean,
|
||||
@RequestBody Map<String, String> map,
|
||||
@RequestBody List<TestBean> list,
|
||||
@RequestBody Mono<List<TestBean>> monoList,
|
||||
@RequestBody Set<TestBean> set,
|
||||
@RequestBody TestBean[] array,
|
||||
TestBean paramWithoutAnnotation) {
|
||||
@@ -361,4 +398,47 @@ public class RequestBodyArgumentResolverTests {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static abstract class AbstractParameterizedController<DTO extends Identifiable> {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void handleDto(@RequestBody DTO dto) {}
|
||||
}
|
||||
|
||||
private static class ConcreteParameterizedController extends AbstractParameterizedController<SimpleBean> {
|
||||
}
|
||||
|
||||
private interface Identifiable extends Serializable {
|
||||
|
||||
Long getId();
|
||||
|
||||
void setId(Long id);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "serial" })
|
||||
private static class SimpleBean implements Identifiable {
|
||||
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
@Override
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user