Add BindingContext

This commit adds a BindingContext to be used in spring-web-reactive
@RequestMapping infrastructure (comparable to WebDataBinderFactory in
spring-web-mvc) for access to the default model, data binding,
validation, and type conversion purposes.

Issue: SPR-14541
This commit is contained in:
Rossen Stoyanchev
2016-10-10 06:06:32 -04:00
parent cabb253269
commit d87aa40efe
26 changed files with 277 additions and 132 deletions

View File

@@ -26,8 +26,6 @@ import org.springframework.http.HttpMethod;
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
import org.springframework.tests.TestSubscriber;
import org.springframework.ui.ExtendedModelMap;
import org.springframework.ui.ModelMap;
import org.springframework.web.reactive.HandlerResult;
import org.springframework.web.reactive.result.ResolvableMethod;
import org.springframework.web.server.ServerWebExchange;
@@ -50,8 +48,6 @@ public class InvocableHandlerMethodTests {
private ServerWebExchange exchange;
private ModelMap model = new ExtendedModelMap();
@Before
public void setUp() throws Exception {
@@ -65,7 +61,7 @@ public class InvocableHandlerMethodTests {
@Test
public void invokeMethodWithNoArguments() throws Exception {
InvocableHandlerMethod hm = handlerMethod("noArgs");
Mono<HandlerResult> mono = hm.invokeForRequest(this.exchange, this.model);
Mono<HandlerResult> mono = hm.invokeForRequest(this.exchange, new BindingContext());
assertHandlerResultValue(mono, "success");
}
@@ -74,7 +70,7 @@ public class InvocableHandlerMethodTests {
public void invokeMethodWithNoValue() throws Exception {
InvocableHandlerMethod hm = handlerMethod("singleArg");
addResolver(hm, Mono.empty());
Mono<HandlerResult> mono = hm.invokeForRequest(this.exchange, this.model);
Mono<HandlerResult> mono = hm.invokeForRequest(this.exchange, new BindingContext());
assertHandlerResultValue(mono, "success:null");
}
@@ -83,7 +79,7 @@ public class InvocableHandlerMethodTests {
public void invokeMethodWithValue() throws Exception {
InvocableHandlerMethod hm = handlerMethod("singleArg");
addResolver(hm, Mono.just("value1"));
Mono<HandlerResult> mono = hm.invokeForRequest(this.exchange, this.model);
Mono<HandlerResult> mono = hm.invokeForRequest(this.exchange, new BindingContext());
assertHandlerResultValue(mono, "success:value1");
}
@@ -91,7 +87,7 @@ public class InvocableHandlerMethodTests {
@Test
public void noMatchingResolver() throws Exception {
InvocableHandlerMethod hm = handlerMethod("singleArg");
Mono<HandlerResult> mono = hm.invokeForRequest(this.exchange, this.model);
Mono<HandlerResult> mono = hm.invokeForRequest(this.exchange, new BindingContext());
TestSubscriber.subscribe(mono)
.assertError(IllegalStateException.class)
@@ -103,7 +99,7 @@ public class InvocableHandlerMethodTests {
public void resolverThrowsException() throws Exception {
InvocableHandlerMethod hm = handlerMethod("singleArg");
addResolver(hm, Mono.error(new UnsupportedMediaTypeStatusException("boo")));
Mono<HandlerResult> mono = hm.invokeForRequest(this.exchange, this.model);
Mono<HandlerResult> mono = hm.invokeForRequest(this.exchange, new BindingContext());
TestSubscriber.subscribe(mono)
.assertError(UnsupportedMediaTypeStatusException.class)
@@ -114,7 +110,7 @@ public class InvocableHandlerMethodTests {
public void illegalArgumentExceptionIsWrappedWithInvocationDetails() throws Exception {
InvocableHandlerMethod hm = handlerMethod("singleArg");
addResolver(hm, Mono.just(1));
Mono<HandlerResult> mono = hm.invokeForRequest(this.exchange, this.model);
Mono<HandlerResult> mono = hm.invokeForRequest(this.exchange, new BindingContext());
TestSubscriber.subscribe(mono)
.assertError(IllegalStateException.class)
@@ -126,7 +122,7 @@ public class InvocableHandlerMethodTests {
@Test
public void invocationTargetExceptionIsUnwrapped() throws Exception {
InvocableHandlerMethod hm = handlerMethod("exceptionMethod");
Mono<HandlerResult> mono = hm.invokeForRequest(this.exchange, this.model);
Mono<HandlerResult> mono = hm.invokeForRequest(this.exchange, new BindingContext());
TestSubscriber.subscribe(mono)
.assertError(IllegalStateException.class)

View File

@@ -35,13 +35,11 @@ import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Controller;
import org.springframework.tests.TestSubscriber;
import org.springframework.ui.ExtendedModelMap;
import org.springframework.ui.ModelMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
@@ -376,8 +374,9 @@ public class RequestMappingInfoHandlerMappingTests {
ServerWebExchange exchange = createExchange(HttpMethod.OPTIONS, requestURI);
HandlerMethod handlerMethod = (HandlerMethod) this.handlerMapping.getHandler(exchange).block();
ModelMap model = new ExtendedModelMap();
Mono<HandlerResult> mono = new InvocableHandlerMethod(handlerMethod).invokeForRequest(exchange, model);
BindingContext bindingContext = new BindingContext();
InvocableHandlerMethod invocable = new InvocableHandlerMethod(handlerMethod);
Mono<HandlerResult> mono = invocable.invokeForRequest(exchange, bindingContext);
HandlerResult result = mono.block();
assertNotNull(result);

View File

@@ -34,6 +34,7 @@ import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.tests.TestSubscriber;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.reactive.result.method.BindingContext;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.ServerWebInputException;
import org.springframework.web.server.adapter.DefaultServerWebExchange;
@@ -59,6 +60,8 @@ public class CookieValueMethodArgumentResolverTests {
private MethodParameter cookieStringParameter;
private MethodParameter stringParameter;
private BindingContext bindingContext = new BindingContext();
@Before
public void setUp() throws Exception {
@@ -90,7 +93,9 @@ public class CookieValueMethodArgumentResolverTests {
HttpCookie expected = new HttpCookie("name", "foo");
this.exchange.getRequest().getCookies().add(expected.getName(), expected);
Mono<Object> mono = this.resolver.resolveArgument(this.cookieParameter, null, this.exchange);
Mono<Object> mono = this.resolver.resolveArgument(
this.cookieParameter, this.bindingContext, this.exchange);
assertEquals(expected, mono.block());
}
@@ -99,14 +104,16 @@ public class CookieValueMethodArgumentResolverTests {
HttpCookie cookie = new HttpCookie("name", "foo");
this.exchange.getRequest().getCookies().add(cookie.getName(), cookie);
Mono<Object> mono = this.resolver.resolveArgument(this.cookieStringParameter, null, this.exchange);
Mono<Object> mono = this.resolver.resolveArgument(
this.cookieStringParameter, this.bindingContext, this.exchange);
assertEquals("Invalid result", cookie.getValue(), mono.block());
}
@Test
public void resolveCookieDefaultValue() {
Mono<Object> mono = this.resolver.resolveArgument(this.cookieStringParameter, null, this.exchange);
Object result = mono.block();
Object result = this.resolver.resolveArgument(
this.cookieStringParameter, this.bindingContext, this.exchange).block();
assertTrue(result instanceof String);
assertEquals("bar", result);
@@ -114,7 +121,7 @@ public class CookieValueMethodArgumentResolverTests {
@Test
public void notFound() {
Mono<Object> mono = resolver.resolveArgument(this.cookieParameter, null, this.exchange);
Mono<Object> mono = resolver.resolveArgument(this.cookieParameter, this.bindingContext, this.exchange);
TestSubscriber
.subscribe(mono)
.assertError(ServerWebInputException.class);

View File

@@ -31,6 +31,7 @@ import org.springframework.http.HttpMethod;
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.reactive.result.method.BindingContext;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.adapter.DefaultServerWebExchange;
import org.springframework.web.server.session.MockWebSessionManager;
@@ -82,7 +83,9 @@ public class ExpressionValueMethodArgumentResolverTests {
public void resolveSystemProperty() throws Exception {
System.setProperty("systemProperty", "22");
try {
Mono<Object> mono = this.resolver.resolveArgument(this.paramSystemProperty, null, this.exchange);
Mono<Object> mono = this.resolver.resolveArgument(
this.paramSystemProperty, new BindingContext(), this.exchange);
Object value = mono.block();
assertEquals(22, value);
}

View File

@@ -46,9 +46,9 @@ import org.springframework.http.codec.HttpMessageReader;
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
import org.springframework.tests.TestSubscriber;
import org.springframework.ui.ExtendedModelMap;
import org.springframework.validation.Validator;
import org.springframework.web.reactive.result.ResolvableMethod;
import org.springframework.web.reactive.result.method.BindingContext;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.ServerWebInputException;
import org.springframework.web.server.adapter.DefaultServerWebExchange;
@@ -304,7 +304,7 @@ public class HttpEntityArgumentResolverTests {
this.request.setBody(body);
MethodParameter param = this.testMethod.resolveParam(type);
Mono<Object> result = this.resolver.resolveArgument(param, new ExtendedModelMap(), this.exchange);
Mono<Object> result = this.resolver.resolveArgument(param, new BindingContext(), this.exchange);
Object value = result.block(Duration.ofSeconds(5));
assertNotNull(value);
@@ -317,7 +317,7 @@ public class HttpEntityArgumentResolverTests {
@SuppressWarnings("unchecked")
private <T> HttpEntity<T> resolveValueWithEmptyBody(ResolvableType type) {
MethodParameter param = this.testMethod.resolveParam(type);
Mono<Object> result = this.resolver.resolveArgument(param, new ExtendedModelMap(), this.exchange);
Mono<Object> result = this.resolver.resolveArgument(param, new BindingContext(), this.exchange);
HttpEntity<String> httpEntity = (HttpEntity<String>) result.block(Duration.ofSeconds(5));
assertEquals(this.request.getHeaders(), httpEntity.getHeaders());

View File

@@ -18,8 +18,6 @@ package org.springframework.web.reactive.result.method.annotation;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
@@ -41,8 +39,6 @@ import rx.Single;
import org.springframework.core.MethodParameter;
import org.springframework.core.ResolvableType;
import org.springframework.core.codec.Decoder;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.http.HttpMethod;
import org.springframework.http.codec.DecoderHttpMessageReader;
import org.springframework.http.codec.HttpMessageReader;
@@ -61,8 +57,12 @@ import org.springframework.web.server.UnsupportedMediaTypeStatusException;
import org.springframework.web.server.adapter.DefaultServerWebExchange;
import org.springframework.web.server.session.MockWebSessionManager;
import static org.junit.Assert.*;
import static org.springframework.core.ResolvableType.*;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.springframework.core.ResolvableType.forClass;
import static org.springframework.core.ResolvableType.forClassWithGenerics;
/**
* Unit tests for {@link AbstractMessageReaderArgumentResolver}.
@@ -302,12 +302,6 @@ public class MessageReaderArgumentResolverTests {
return new AbstractMessageReaderArgumentResolver(readers, new TestBeanValidator()) {};
}
private DataBuffer dataBuffer(String body) {
byte[] bytes = body.getBytes(StandardCharsets.UTF_8);
ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
return new DefaultDataBufferFactory().wrap(byteBuffer);
}
@SuppressWarnings("unused")
private void handle(

View File

@@ -27,12 +27,12 @@ import reactor.core.publisher.Mono;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpMethod;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.reactive.HandlerMapping;
import org.springframework.web.reactive.result.method.BindingContext;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.adapter.DefaultServerWebExchange;
import org.springframework.web.server.session.MockWebSessionManager;
@@ -86,7 +86,7 @@ public class PathVariableMapMethodArgumentResolverTests {
uriTemplateVars.put("name2", "value2");
this.exchange.getAttributes().put(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVars);
Mono<Object> mono = this.resolver.resolveArgument(this.paramMap, new ModelMap(), this.exchange);
Mono<Object> mono = this.resolver.resolveArgument(this.paramMap, new BindingContext(), this.exchange);
Object result = mono.block();
assertEquals(uriTemplateVars, result);
@@ -94,7 +94,7 @@ public class PathVariableMapMethodArgumentResolverTests {
@Test
public void resolveArgumentNoUriVars() throws Exception {
Mono<Object> mono = this.resolver.resolveArgument(this.paramMap, new ModelMap(), this.exchange);
Mono<Object> mono = this.resolver.resolveArgument(this.paramMap, new BindingContext(), this.exchange);
Object result = mono.block();
assertEquals(Collections.emptyMap(), result);

View File

@@ -30,14 +30,14 @@ import org.springframework.core.annotation.SynthesizingMethodParameter;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.http.HttpMethod;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.tests.TestSubscriber;
import org.springframework.ui.ModelMap;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.reactive.HandlerMapping;
import org.springframework.web.reactive.result.method.BindingContext;
import org.springframework.web.server.ServerErrorException;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.adapter.DefaultServerWebExchange;
@@ -98,7 +98,8 @@ public class PathVariableMethodArgumentResolverTests {
uriTemplateVars.put("name", "value");
this.exchange.getAttributes().put(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVars);
Mono<Object> mono = this.resolver.resolveArgument(this.paramNamedString, new ModelMap(), this.exchange);
BindingContext bindingContext = new BindingContext();
Mono<Object> mono = this.resolver.resolveArgument(this.paramNamedString, bindingContext, this.exchange);
Object result = mono.block();
assertEquals("value", result);
}
@@ -109,7 +110,8 @@ public class PathVariableMethodArgumentResolverTests {
uriTemplateVars.put("name", "value");
this.exchange.getAttributes().put(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVars);
Mono<Object> mono = this.resolver.resolveArgument(this.paramNotRequired, new ModelMap(), this.exchange);
BindingContext bindingContext = new BindingContext();
Mono<Object> mono = this.resolver.resolveArgument(this.paramNotRequired, bindingContext, this.exchange);
Object result = mono.block();
assertEquals("value", result);
}
@@ -120,14 +122,16 @@ public class PathVariableMethodArgumentResolverTests {
uriTemplateVars.put("name", "value");
this.exchange.getAttributes().put(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVars);
Mono<Object> mono = this.resolver.resolveArgument(this.paramOptional, new ModelMap(), this.exchange);
BindingContext bindingContext = new BindingContext();
Mono<Object> mono = this.resolver.resolveArgument(this.paramOptional, bindingContext, this.exchange);
Object result = mono.block();
assertEquals(Optional.of("value"), result);
}
@Test
public void handleMissingValue() throws Exception {
Mono<Object> mono = this.resolver.resolveArgument(this.paramNamedString, new ModelMap(), this.exchange);
BindingContext bindingContext = new BindingContext();
Mono<Object> mono = this.resolver.resolveArgument(this.paramNamedString, bindingContext, this.exchange);
TestSubscriber
.subscribe(mono)
.assertError(ServerErrorException.class);
@@ -135,7 +139,8 @@ public class PathVariableMethodArgumentResolverTests {
@Test
public void nullIfNotRequired() throws Exception {
Mono<Object> mono = this.resolver.resolveArgument(this.paramNotRequired, new ModelMap(), this.exchange);
BindingContext bindingContext = new BindingContext();
Mono<Object> mono = this.resolver.resolveArgument(this.paramNotRequired, bindingContext, this.exchange);
TestSubscriber
.subscribe(mono)
.assertComplete()
@@ -144,7 +149,8 @@ public class PathVariableMethodArgumentResolverTests {
@Test
public void wrapEmptyWithOptional() throws Exception {
Mono<Object> mono = this.resolver.resolveArgument(this.paramOptional, new ModelMap(), this.exchange);
BindingContext bindingContext = new BindingContext();
Mono<Object> mono = this.resolver.resolveArgument(this.paramOptional, bindingContext, this.exchange);
Object result = mono.block();
TestSubscriber
.subscribe(mono)

View File

@@ -36,6 +36,7 @@ import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.tests.TestSubscriber;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.reactive.result.method.BindingContext;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.ServerWebInputException;
import org.springframework.web.server.adapter.DefaultServerWebExchange;
@@ -88,14 +89,14 @@ public class RequestAttributeMethodArgumentResolverTests {
@Test
public void resolve() throws Exception {
MethodParameter param = initMethodParameter(0);
Mono<Object> mono = this.resolver.resolveArgument(param, null, this.exchange);
Mono<Object> mono = this.resolver.resolveArgument(param, new BindingContext(), this.exchange);
TestSubscriber
.subscribe(mono)
.assertError(ServerWebInputException.class);
Foo foo = new Foo();
this.exchange.getAttributes().put("foo", foo);
mono = this.resolver.resolveArgument(param, null, this.exchange);
mono = this.resolver.resolveArgument(param, new BindingContext(), this.exchange);
assertSame(foo, mono.block());
}
@@ -104,33 +105,34 @@ public class RequestAttributeMethodArgumentResolverTests {
MethodParameter param = initMethodParameter(1);
Foo foo = new Foo();
this.exchange.getAttributes().put("specialFoo", foo);
Mono<Object> mono = this.resolver.resolveArgument(param, null, this.exchange);
Mono<Object> mono = this.resolver.resolveArgument(param, new BindingContext(), this.exchange);
assertSame(foo, mono.block());
}
@Test
public void resolveNotRequired() throws Exception {
MethodParameter param = initMethodParameter(2);
Mono<Object> mono = this.resolver.resolveArgument(param, null, this.exchange);
Mono<Object> mono = this.resolver.resolveArgument(param, new BindingContext(), this.exchange);
assertNull(mono.block());
Foo foo = new Foo();
this.exchange.getAttributes().put("foo", foo);
mono = this.resolver.resolveArgument(param, null, this.exchange);
mono = this.resolver.resolveArgument(param, new BindingContext(), this.exchange);
assertSame(foo, mono.block());
}
@Test
public void resolveOptional() throws Exception {
MethodParameter param = initMethodParameter(3);
Mono<Object> mono = this.resolver.resolveArgument(param, null, this.exchange);
Mono<Object> mono = this.resolver.resolveArgument(param, new BindingContext(), this.exchange);
assertNotNull(mono.block());
assertEquals(Optional.class, mono.block().getClass());
assertFalse(((Optional) mono.block()).isPresent());
Foo foo = new Foo();
this.exchange.getAttributes().put("foo", foo);
mono = this.resolver.resolveArgument(param, null, this.exchange);
mono = this.resolver.resolveArgument(param, new BindingContext(), this.exchange);
assertNotNull(mono.block());
assertEquals(Optional.class, mono.block().getClass());

View File

@@ -39,10 +39,10 @@ import org.springframework.http.codec.HttpMessageReader;
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
import org.springframework.tests.TestSubscriber;
import org.springframework.ui.ExtendedModelMap;
import org.springframework.validation.Validator;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.reactive.result.ResolvableMethod;
import org.springframework.web.reactive.result.method.BindingContext;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.ServerWebInputException;
import org.springframework.web.server.adapter.DefaultServerWebExchange;
@@ -213,7 +213,7 @@ public class RequestBodyArgumentResolverTests {
@SuppressWarnings("unchecked")
private <T> T resolveValueWithEmptyBody(ResolvableType bodyType, boolean isRequired) {
MethodParameter param = this.testMethod.resolveParam(bodyType, requestBody(isRequired));
Mono<Object> result = this.resolver.resolveArgument(param, new ExtendedModelMap(), this.exchange);
Mono<Object> result = this.resolver.resolveArgument(param, new BindingContext(), this.exchange);
Object value = result.block(Duration.ofSeconds(5));
if (value != null) {

View File

@@ -39,6 +39,7 @@ import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.tests.TestSubscriber;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.reactive.result.method.BindingContext;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.ServerWebInputException;
import org.springframework.web.server.adapter.DefaultServerWebExchange;
@@ -70,6 +71,8 @@ public class RequestHeaderMethodArgumentResolverTests {
private ServerWebExchange exchange;
private BindingContext bindingContext = new BindingContext();
@Before
public void setUp() throws Exception {
@@ -107,7 +110,9 @@ public class RequestHeaderMethodArgumentResolverTests {
String expected = "foo";
this.exchange.getRequest().getHeaders().add("name", expected);
Mono<Object> mono = this.resolver.resolveArgument(paramNamedDefaultValueStringHeader, null, this.exchange);
Mono<Object> mono = this.resolver.resolveArgument(
this.paramNamedDefaultValueStringHeader, this.bindingContext, this.exchange);
Object result = mono.block();
assertTrue(result instanceof String);
assertEquals(expected, result);
@@ -118,7 +123,9 @@ public class RequestHeaderMethodArgumentResolverTests {
String[] expected = new String[] {"foo", "bar"};
this.exchange.getRequest().getHeaders().put("name", Arrays.asList(expected));
Mono<Object> mono = this.resolver.resolveArgument(paramNamedValueStringArray, null, this.exchange);
Mono<Object> mono = this.resolver.resolveArgument(
this.paramNamedValueStringArray, this.bindingContext, this.exchange);
Object result = mono.block();
assertTrue(result instanceof String[]);
assertArrayEquals(expected, (String[]) result);
@@ -126,7 +133,9 @@ public class RequestHeaderMethodArgumentResolverTests {
@Test
public void resolveDefaultValue() throws Exception {
Mono<Object> mono = this.resolver.resolveArgument(paramNamedDefaultValueStringHeader, null, this.exchange);
Mono<Object> mono = this.resolver.resolveArgument(
this.paramNamedDefaultValueStringHeader, this.bindingContext, this.exchange);
Object result = mono.block();
assertTrue(result instanceof String);
assertEquals("bar", result);
@@ -136,7 +145,9 @@ public class RequestHeaderMethodArgumentResolverTests {
public void resolveDefaultValueFromSystemProperty() throws Exception {
System.setProperty("systemProperty", "bar");
try {
Mono<Object> mono = this.resolver.resolveArgument(paramSystemProperty, null, this.exchange);
Mono<Object> mono = this.resolver.resolveArgument(
this.paramSystemProperty, this.bindingContext, this.exchange);
Object result = mono.block();
assertTrue(result instanceof String);
assertEquals("bar", result);
@@ -153,7 +164,9 @@ public class RequestHeaderMethodArgumentResolverTests {
System.setProperty("systemProperty", "bar");
try {
Mono<Object> mono = this.resolver.resolveArgument(paramResolvedNameWithExpression, null, this.exchange);
Mono<Object> mono = this.resolver.resolveArgument(
this.paramResolvedNameWithExpression, this.bindingContext, this.exchange);
Object result = mono.block();
assertTrue(result instanceof String);
assertEquals(expected, result);
@@ -170,7 +183,9 @@ public class RequestHeaderMethodArgumentResolverTests {
System.setProperty("systemProperty", "bar");
try {
Mono<Object> mono = this.resolver.resolveArgument(paramResolvedNameWithPlaceholder, null, this.exchange);
Mono<Object> mono = this.resolver.resolveArgument(
this.paramResolvedNameWithPlaceholder, this.bindingContext, this.exchange);
Object result = mono.block();
assertTrue(result instanceof String);
assertEquals(expected, result);
@@ -182,7 +197,9 @@ public class RequestHeaderMethodArgumentResolverTests {
@Test
public void notFound() throws Exception {
Mono<Object> mono = resolver.resolveArgument(paramNamedValueStringArray, null, this.exchange);
Mono<Object> mono = resolver.resolveArgument(
this.paramNamedValueStringArray, this.bindingContext, this.exchange);
TestSubscriber
.subscribe(mono)
.assertError(ServerWebInputException.class);
@@ -194,7 +211,7 @@ public class RequestHeaderMethodArgumentResolverTests {
String rfc1123val = "Thu, 21 Apr 2016 17:11:08 +0100";
this.exchange.getRequest().getHeaders().add("name", rfc1123val);
Mono<Object> mono = this.resolver.resolveArgument(paramDate, null, this.exchange);
Mono<Object> mono = this.resolver.resolveArgument(this.paramDate, this.bindingContext, this.exchange);
Object result = mono.block();
assertTrue(result instanceof Date);
@@ -206,7 +223,7 @@ public class RequestHeaderMethodArgumentResolverTests {
String rfc1123val = "Thu, 21 Apr 2016 17:11:08 +0100";
this.exchange.getRequest().getHeaders().add("name", rfc1123val);
Mono<Object> mono = this.resolver.resolveArgument(paramInstant, null, this.exchange);
Mono<Object> mono = this.resolver.resolveArgument(this.paramInstant, this.bindingContext, this.exchange);
Object result = mono.block();
assertTrue(result instanceof Instant);

View File

@@ -39,6 +39,7 @@ import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.tests.TestSubscriber;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.reactive.result.method.BindingContext;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.ServerWebInputException;
import org.springframework.web.server.adapter.DefaultServerWebExchange;
@@ -71,6 +72,8 @@ public class RequestParamMethodArgumentResolverTests {
private MethodParameter paramNotRequired;
private MethodParameter paramOptional;
private BindingContext bindingContext = new BindingContext();
@Before @SuppressWarnings("ConfusingArgumentToVarargsMethod")
public void setUp() throws Exception {
@@ -117,9 +120,10 @@ public class RequestParamMethodArgumentResolverTests {
String expected = "foo";
this.exchange.getRequest().getQueryParams().set("name", expected);
Mono<Object> mono = this.resolver.resolveArgument(this.paramNamedDefaultValueString, null, this.exchange);
Object result = mono.block();
Mono<Object> mono = this.resolver.resolveArgument(
this.paramNamedDefaultValueString, this.bindingContext, this.exchange);
Object result = mono.block();
assertTrue(result instanceof String);
assertEquals("Invalid result", expected, result);
}
@@ -129,25 +133,29 @@ public class RequestParamMethodArgumentResolverTests {
String[] expected = {"foo", "bar"};
this.exchange.getRequest().getQueryParams().put("name", Arrays.asList(expected));
Mono<Object> mono = this.resolver.resolveArgument(this.paramNamedStringArray, null, this.exchange);
Object result = mono.block();
Mono<Object> mono = this.resolver.resolveArgument(
this.paramNamedStringArray, this.bindingContext, this.exchange);
Object result = mono.block();
assertTrue(result instanceof String[]);
assertArrayEquals(expected, (String[]) result);
}
@Test
public void resolveDefaultValue() throws Exception {
Mono<Object> mono = this.resolver.resolveArgument(paramNamedDefaultValueString, null, this.exchange);
Object result = mono.block();
Mono<Object> mono = this.resolver.resolveArgument(
this.paramNamedDefaultValueString, this.bindingContext, this.exchange);
Object result = mono.block();
assertTrue(result instanceof String);
assertEquals("Invalid result", "bar", result);
}
@Test
public void missingRequestParam() throws Exception {
Mono<Object> mono = this.resolver.resolveArgument(paramNamedStringArray, null, this.exchange);
Mono<Object> mono = this.resolver.resolveArgument(
this.paramNamedStringArray, this.bindingContext, this.exchange);
TestSubscriber
.subscribe(mono)
.assertError(ServerWebInputException.class);
@@ -156,57 +164,63 @@ public class RequestParamMethodArgumentResolverTests {
@Test
public void resolveSimpleTypeParam() throws Exception {
this.exchange.getRequest().getQueryParams().set("stringNotAnnot", "plainValue");
Mono<Object> mono = this.resolver.resolveArgument(paramStringNotAnnot, null, this.exchange);
Object result = mono.block();
Mono<Object> mono = this.resolver.resolveArgument(
this.paramStringNotAnnot, this.bindingContext, this.exchange);
Object result = mono.block();
assertTrue(result instanceof String);
assertEquals("plainValue", result);
}
@Test // SPR-8561
public void resolveSimpleTypeParamToNull() throws Exception {
Mono<Object> mono = this.resolver.resolveArgument(paramStringNotAnnot, null, this.exchange);
Object result = mono.block();
Mono<Object> mono = this.resolver.resolveArgument(
this.paramStringNotAnnot, this.bindingContext, this.exchange);
Object result = mono.block();
assertNull(result);
}
@Test // SPR-10180
public void resolveEmptyValueToDefault() throws Exception {
this.exchange.getRequest().getQueryParams().set("name", "");
Mono<Object> mono = this.resolver.resolveArgument(paramNamedDefaultValueString, null, this.exchange);
Object result = mono.block();
Mono<Object> mono = this.resolver.resolveArgument(
this.paramNamedDefaultValueString, this.bindingContext, this.exchange);
Object result = mono.block();
assertEquals("bar", result);
}
@Test
public void resolveEmptyValueWithoutDefault() throws Exception {
this.exchange.getRequest().getQueryParams().set("stringNotAnnot", "");
Mono<Object> mono = this.resolver.resolveArgument(paramStringNotAnnot, null, this.exchange);
Object result = mono.block();
Mono<Object> mono = this.resolver.resolveArgument(
this.paramStringNotAnnot, this.bindingContext, this.exchange);
Object result = mono.block();
assertEquals("", result);
}
@Test
public void resolveEmptyValueRequiredWithoutDefault() throws Exception {
this.exchange.getRequest().getQueryParams().set("name", "");
Mono<Object> mono = this.resolver.resolveArgument(paramRequired, null, this.exchange);
Object result = mono.block();
Mono<Object> mono = this.resolver.resolveArgument(
this.paramRequired, this.bindingContext, this.exchange);
Object result = mono.block();
assertEquals("", result);
}
@Test
public void resolveOptionalParamValue() throws Exception {
Mono<Object> mono = this.resolver.resolveArgument(paramOptional, null, this.exchange);
Object result = mono.block();
Mono<Object> mono = this.resolver.resolveArgument(
this.paramOptional, this.bindingContext, this.exchange);
Object result = mono.block();
assertEquals(Optional.empty(), result);
this.exchange.getRequest().getQueryParams().set("name", "123");
mono = resolver.resolveArgument(paramOptional, null, this.exchange);
mono = this.resolver.resolveArgument(this.paramOptional, this.bindingContext, this.exchange);
result = mono.block();
assertEquals(Optional.class, result.getClass());

View File

@@ -21,12 +21,12 @@ import reactor.core.publisher.Mono;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpMethod;
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.ui.ModelMap;
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
import org.springframework.web.reactive.result.ResolvableMethod;
import org.springframework.web.reactive.result.method.BindingContext;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebSession;
import org.springframework.web.server.adapter.DefaultServerWebExchange;
@@ -84,7 +84,7 @@ public class ServerWebExchangeArgumentResolverTests {
}
private void testResolveArgument(MethodParameter parameter, Object expected) {
Mono<Object> mono = this.resolver.resolveArgument(parameter, new ModelMap(), this.exchange);
Mono<Object> mono = this.resolver.resolveArgument(parameter, new BindingContext(), this.exchange);
assertSame(expected, mono.block());
}

View File

@@ -36,6 +36,7 @@ import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.tests.TestSubscriber;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.annotation.SessionAttribute;
import org.springframework.web.reactive.result.method.BindingContext;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.ServerWebInputException;
import org.springframework.web.server.WebSession;
@@ -95,14 +96,14 @@ public class SessionAttributeMethodArgumentResolverTests {
@Test
public void resolve() throws Exception {
MethodParameter param = initMethodParameter(0);
Mono<Object> mono = this.resolver.resolveArgument(param, null, this.exchange);
Mono<Object> mono = this.resolver.resolveArgument(param, new BindingContext(), this.exchange);
TestSubscriber
.subscribe(mono)
.assertError(ServerWebInputException.class);
Foo foo = new Foo();
when(this.session.getAttribute("foo")).thenReturn(Optional.of(foo));
mono = this.resolver.resolveArgument(param, null, this.exchange);
mono = this.resolver.resolveArgument(param, new BindingContext(), this.exchange);
assertSame(foo, mono.block());
}
@@ -111,33 +112,33 @@ public class SessionAttributeMethodArgumentResolverTests {
MethodParameter param = initMethodParameter(1);
Foo foo = new Foo();
when(this.session.getAttribute("specialFoo")).thenReturn(Optional.of(foo));
Mono<Object> mono = this.resolver.resolveArgument(param, null, this.exchange);
Mono<Object> mono = this.resolver.resolveArgument(param, new BindingContext(), this.exchange);
assertSame(foo, mono.block());
}
@Test
public void resolveNotRequired() throws Exception {
MethodParameter param = initMethodParameter(2);
Mono<Object> mono = this.resolver.resolveArgument(param, null, this.exchange);
Mono<Object> mono = this.resolver.resolveArgument(param, new BindingContext(), this.exchange);
assertNull(mono.block());
Foo foo = new Foo();
when(this.session.getAttribute("foo")).thenReturn(Optional.of(foo));
mono = this.resolver.resolveArgument(param, null, this.exchange);
mono = this.resolver.resolveArgument(param, new BindingContext(), this.exchange);
assertSame(foo, mono.block());
}
@Test
public void resolveOptional() throws Exception {
MethodParameter param = initMethodParameter(3);
Mono<Object> mono = this.resolver.resolveArgument(param, null, this.exchange);
Mono<Object> mono = this.resolver.resolveArgument(param, new BindingContext(), this.exchange);
assertNotNull(mono.block());
assertEquals(Optional.class, mono.block().getClass());
assertFalse(((Optional) mono.block()).isPresent());
Foo foo = new Foo();
when(this.session.getAttribute("foo")).thenReturn(Optional.of(foo));
mono = this.resolver.resolveArgument(param, null, this.exchange);
mono = this.resolver.resolveArgument(param, new BindingContext(), this.exchange);
assertNotNull(mono.block());
assertEquals(Optional.class, mono.block().getClass());