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

@ -0,0 +1,83 @@
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.reactive.result.method;
import reactor.core.publisher.Mono;
import org.springframework.ui.ModelMap;
import org.springframework.validation.support.BindingAwareModelMap;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.WebExchangeDataBinder;
import org.springframework.web.bind.support.WebBindingInitializer;
import org.springframework.web.server.ServerWebExchange;
/**
* A context for binding requests to method arguments that provides access to
* the default model, data binding, validation, and type conversion.
*
* @author Rossen Stoyanchev
* @since 5.0
*/
public class BindingContext {
private final ModelMap model = new BindingAwareModelMap();
private final WebBindingInitializer initializer;
public BindingContext() {
this(null);
}
public BindingContext(WebBindingInitializer initializer) {
this.initializer = initializer;
}
/**
* Return the default model.
*/
public ModelMap getModel() {
return this.model;
}
/**
* Create a {@link WebExchangeDataBinder} for the given object.
* @param exchange the current exchange
* @param target the object to create a data binder for, or {@code null} if
* creating a binder for a simple type
* @param objectName the name of the target object
* @return a Mono for the created {@link WebDataBinder} instance
*/
public Mono<WebExchangeDataBinder> createBinder(ServerWebExchange exchange, Object target,
String objectName) {
WebExchangeDataBinder dataBinder = createBinderInstance(target, objectName);
if (this.initializer != null) {
this.initializer.initBinder(dataBinder);
}
return initBinder(dataBinder, exchange);
}
protected WebExchangeDataBinder createBinderInstance(Object target, String objectName) {
return new WebExchangeDataBinder(target, objectName);
}
protected Mono<WebExchangeDataBinder> initBinder(WebExchangeDataBinder dataBinder, ServerWebExchange exchange) {
return Mono.just(dataBinder);
}
}

View File

@ -19,11 +19,13 @@ package org.springframework.web.reactive.result.method;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
import org.springframework.ui.ModelMap;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
/** /**
* Strategy interface for resolving method parameters into argument values in
* the context of a given request.
*
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @since 5.0 * @since 5.0
*/ */
@ -37,9 +39,10 @@ public interface HandlerMethodArgumentResolver {
* does not resolve to any value, which will result in {@code null} passed * does not resolve to any value, which will result in {@code null} passed
* as the argument value. * as the argument value.
* @param parameter the method parameter * @param parameter the method parameter
* @param model the implicit model for request handling * @param bindingContext the binding context to use
* @param exchange the current exchange * @param exchange the current exchange
*/ */
Mono<Object> resolveArgument(MethodParameter parameter, ModelMap model, ServerWebExchange exchange); Mono<Object> resolveArgument(MethodParameter parameter, BindingContext bindingContext,
ServerWebExchange exchange);
} }

View File

@ -81,18 +81,19 @@ public class InvocableHandlerMethod extends HandlerMethod {
/** /**
* Invoke the method and return a Publisher for the return value. * Invoke the method and return a Publisher for the return value.
* @param exchange the current exchange * @param exchange the current exchange
* @param model the model for request handling * @param bindingContext the binding context to use
* @param providedArgs optional list of argument values to check by type * @param providedArgs optional list of argument values to check by type
* (via {@code instanceof}) for resolving method arguments. * (via {@code instanceof}) for resolving method arguments.
* @return Publisher that produces a single HandlerResult or an error signal; * @return Publisher that produces a single HandlerResult or an error signal;
* never throws an exception * never throws an exception
*/ */
public Mono<HandlerResult> invokeForRequest(ServerWebExchange exchange, ModelMap model, public Mono<HandlerResult> invokeForRequest(ServerWebExchange exchange,
Object... providedArgs) { BindingContext bindingContext, Object... providedArgs) {
return resolveArguments(exchange, model, providedArgs).then(args -> { return resolveArguments(exchange, bindingContext, providedArgs).then(args -> {
try { try {
Object value = doInvoke(args); Object value = doInvoke(args);
ModelMap model = bindingContext.getModel();
HandlerResult handlerResult = new HandlerResult(this, value, getReturnType(), model); HandlerResult handlerResult = new HandlerResult(this, value, getReturnType(), model);
return Mono.just(handlerResult); return Mono.just(handlerResult);
} }
@ -106,7 +107,9 @@ public class InvocableHandlerMethod extends HandlerMethod {
}); });
} }
private Mono<Object[]> resolveArguments(ServerWebExchange exchange, ModelMap model, Object... providedArgs) { private Mono<Object[]> resolveArguments(ServerWebExchange exchange,
BindingContext bindingContext, Object... providedArgs) {
if (ObjectUtils.isEmpty(getMethodParameters())) { if (ObjectUtils.isEmpty(getMethodParameters())) {
return NO_ARGS; return NO_ARGS;
} }
@ -127,7 +130,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
.findFirst() .findFirst()
.orElseThrow(() -> getArgError("No resolver for ", param, null)); .orElseThrow(() -> getArgError("No resolver for ", param, null));
try { try {
return resolver.resolveArgument(param, model, exchange) return resolver.resolveArgument(param, bindingContext, exchange)
.defaultIfEmpty(NO_VALUE) .defaultIfEmpty(NO_VALUE)
.doOnError(cause -> { .doOnError(cause -> {
if(logger.isDebugEnabled()) { if(logger.isDebugEnabled()) {

View File

@ -32,6 +32,7 @@ import org.springframework.core.convert.ConversionService;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.ValueConstants; import org.springframework.web.bind.annotation.ValueConstants;
import org.springframework.web.reactive.result.method.BindingContext;
import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver; import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver;
import org.springframework.web.server.ServerErrorException; import org.springframework.web.server.ServerErrorException;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
@ -85,7 +86,9 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
@Override @Override
public Mono<Object> resolveArgument(MethodParameter parameter, ModelMap model, ServerWebExchange exchange) { public Mono<Object> resolveArgument(MethodParameter parameter, BindingContext bindingContext,
ServerWebExchange exchange) {
NamedValueInfo namedValueInfo = getNamedValueInfo(parameter); NamedValueInfo namedValueInfo = getNamedValueInfo(parameter);
MethodParameter nestedParameter = parameter.nestedIfOptional(); MethodParameter nestedParameter = parameter.nestedIfOptional();
@ -95,6 +98,8 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
"Specified name must not resolve to null: [" + namedValueInfo.name + "]")); "Specified name must not resolve to null: [" + namedValueInfo.name + "]"));
} }
ModelMap model = bindingContext.getModel();
return resolveName(resolvedName.toString(), nestedParameter, exchange) return resolveName(resolvedName.toString(), nestedParameter, exchange)
.map(arg -> { .map(arg -> {
if ("".equals(arg) && namedValueInfo.defaultValue != null) { if ("".equals(arg) && namedValueInfo.defaultValue != null) {

View File

@ -27,8 +27,8 @@ import org.springframework.http.HttpHeaders;
import org.springframework.http.RequestEntity; import org.springframework.http.RequestEntity;
import org.springframework.http.codec.HttpMessageReader; import org.springframework.http.codec.HttpMessageReader;
import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.ui.ModelMap;
import org.springframework.validation.Validator; import org.springframework.validation.Validator;
import org.springframework.web.reactive.result.method.BindingContext;
import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver; import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
@ -73,7 +73,8 @@ public class HttpEntityArgumentResolver extends AbstractMessageReaderArgumentRes
} }
@Override @Override
public Mono<Object> resolveArgument(MethodParameter param, ModelMap model, ServerWebExchange exchange) { public Mono<Object> resolveArgument(MethodParameter param, BindingContext bindingContext,
ServerWebExchange exchange) {
ResolvableType entityType = ResolvableType.forMethodParameter(param); ResolvableType entityType = ResolvableType.forMethodParameter(param);
MethodParameter bodyParameter = new MethodParameter(param); MethodParameter bodyParameter = new MethodParameter(param);

View File

@ -19,7 +19,7 @@ import reactor.core.publisher.Mono;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.ui.ModelMap; import org.springframework.web.reactive.result.method.BindingContext;
import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver; import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
@ -38,8 +38,10 @@ public class ModelArgumentResolver implements HandlerMethodArgumentResolver {
} }
@Override @Override
public Mono<Object> resolveArgument(MethodParameter parameter, ModelMap model, ServerWebExchange exchange) { public Mono<Object> resolveArgument(MethodParameter parameter, BindingContext bindingContext,
return Mono.just(model); ServerWebExchange exchange) {
return Mono.just(bindingContext.getModel());
} }
} }

View File

@ -23,10 +23,10 @@ import java.util.Optional;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.reactive.HandlerMapping; import org.springframework.web.reactive.HandlerMapping;
import org.springframework.web.reactive.result.method.BindingContext;
import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver; import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
@ -54,7 +54,7 @@ public class PathVariableMapMethodArgumentResolver implements HandlerMethodArgum
* Return a Map with all URI template variables or an empty map. * Return a Map with all URI template variables or an empty map.
*/ */
@Override @Override
public Mono<Object> resolveArgument(MethodParameter parameter, ModelMap model, public Mono<Object> resolveArgument(MethodParameter parameter, BindingContext bindingContext,
ServerWebExchange exchange) { ServerWebExchange exchange) {
String name = HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE; String name = HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE;

View File

@ -23,9 +23,9 @@ import reactor.core.publisher.Mono;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
import org.springframework.core.ReactiveAdapterRegistry; import org.springframework.core.ReactiveAdapterRegistry;
import org.springframework.http.codec.HttpMessageReader; import org.springframework.http.codec.HttpMessageReader;
import org.springframework.ui.ModelMap;
import org.springframework.validation.Validator; import org.springframework.validation.Validator;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.reactive.result.method.BindingContext;
import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver; import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.ServerWebInputException; import org.springframework.web.server.ServerWebInputException;
@ -76,7 +76,9 @@ public class RequestBodyArgumentResolver extends AbstractMessageReaderArgumentRe
} }
@Override @Override
public Mono<Object> resolveArgument(MethodParameter param, ModelMap model, ServerWebExchange exchange) { public Mono<Object> resolveArgument(MethodParameter param, BindingContext bindingContext,
ServerWebExchange exchange) {
boolean isRequired = param.getParameterAnnotation(RequestBody.class).required(); boolean isRequired = param.getParameterAnnotation(RequestBody.class).required();
return readBody(param, isRequired, exchange); return readBody(param, isRequired, exchange);
} }

View File

@ -22,9 +22,9 @@ import reactor.core.publisher.Mono;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.ui.ModelMap;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.reactive.result.method.BindingContext;
import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver; import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
@ -50,7 +50,9 @@ public class RequestHeaderMapMethodArgumentResolver implements HandlerMethodArgu
} }
@Override @Override
public Mono<Object> resolveArgument(MethodParameter parameter, ModelMap model, ServerWebExchange exchange) { public Mono<Object> resolveArgument(MethodParameter parameter, BindingContext bindingContext,
ServerWebExchange exchange) {
HttpHeaders headers = exchange.getRequest().getHeaders(); HttpHeaders headers = exchange.getRequest().getHeaders();
if (MultiValueMap.class.isAssignableFrom(parameter.getParameterType())) { if (MultiValueMap.class.isAssignableFrom(parameter.getParameterType())) {
return Mono.just(headers); return Mono.just(headers);

View File

@ -38,14 +38,13 @@ import org.springframework.core.convert.ConversionService;
import org.springframework.format.support.DefaultFormattingConversionService; import org.springframework.format.support.DefaultFormattingConversionService;
import org.springframework.http.codec.DecoderHttpMessageReader; import org.springframework.http.codec.DecoderHttpMessageReader;
import org.springframework.http.codec.HttpMessageReader; import org.springframework.http.codec.HttpMessageReader;
import org.springframework.ui.ExtendedModelMap;
import org.springframework.ui.ModelMap;
import org.springframework.validation.Validator; import org.springframework.validation.Validator;
import org.springframework.web.bind.support.WebBindingInitializer; import org.springframework.web.bind.support.WebBindingInitializer;
import org.springframework.web.method.HandlerMethod; import org.springframework.web.method.HandlerMethod;
import org.springframework.web.method.annotation.ExceptionHandlerMethodResolver; import org.springframework.web.method.annotation.ExceptionHandlerMethodResolver;
import org.springframework.web.reactive.HandlerAdapter; import org.springframework.web.reactive.HandlerAdapter;
import org.springframework.web.reactive.HandlerResult; import org.springframework.web.reactive.HandlerResult;
import org.springframework.web.reactive.result.method.BindingContext;
import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver; import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver;
import org.springframework.web.reactive.result.method.InvocableHandlerMethod; import org.springframework.web.reactive.result.method.InvocableHandlerMethod;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
@ -257,14 +256,16 @@ public class RequestMappingHandlerAdapter implements HandlerAdapter, BeanFactory
HandlerMethod handlerMethod = (HandlerMethod) handler; HandlerMethod handlerMethod = (HandlerMethod) handler;
InvocableHandlerMethod invocable = new InvocableHandlerMethod(handlerMethod); InvocableHandlerMethod invocable = new InvocableHandlerMethod(handlerMethod);
invocable.setHandlerMethodArgumentResolvers(getArgumentResolvers()); invocable.setHandlerMethodArgumentResolvers(getArgumentResolvers());
ModelMap model = new ExtendedModelMap(); BindingContext bindingContext = new BindingContext(getWebBindingInitializer());
return invocable.invokeForRequest(exchange, model) return invocable.invokeForRequest(exchange, bindingContext)
.map(result -> result.setExceptionHandler(ex -> handleException(ex, handlerMethod, exchange))) .map(result -> result.setExceptionHandler(
.otherwise(ex -> handleException(ex, handlerMethod, exchange)); ex -> handleException(ex, handlerMethod, bindingContext, exchange)))
.otherwise(ex -> handleException(
ex, handlerMethod, bindingContext, exchange));
} }
private Mono<HandlerResult> handleException(Throwable ex, HandlerMethod handlerMethod, private Mono<HandlerResult> handleException(Throwable ex, HandlerMethod handlerMethod,
ServerWebExchange exchange) { BindingContext bindingContext, ServerWebExchange exchange) {
if (ex instanceof Exception) { if (ex instanceof Exception) {
InvocableHandlerMethod invocable = findExceptionHandler(handlerMethod, (Exception) ex); InvocableHandlerMethod invocable = findExceptionHandler(handlerMethod, (Exception) ex);
@ -274,8 +275,8 @@ public class RequestMappingHandlerAdapter implements HandlerAdapter, BeanFactory
logger.debug("Invoking @ExceptionHandler method: " + invocable); logger.debug("Invoking @ExceptionHandler method: " + invocable);
} }
invocable.setHandlerMethodArgumentResolvers(getArgumentResolvers()); invocable.setHandlerMethodArgumentResolvers(getArgumentResolvers());
ExtendedModelMap errorModel = new ExtendedModelMap(); bindingContext.getModel().clear();
return invocable.invokeForRequest(exchange, errorModel, ex); return invocable.invokeForRequest(exchange, bindingContext, ex);
} }
catch (Exception invocationEx) { catch (Exception invocationEx) {
if (logger.isErrorEnabled()) { if (logger.isErrorEnabled()) {

View File

@ -21,10 +21,10 @@ import java.util.Map;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
import org.springframework.ui.ModelMap;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.reactive.result.method.BindingContext;
import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver; import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
@ -57,7 +57,9 @@ public class RequestParamMapMethodArgumentResolver implements HandlerMethodArgum
} }
@Override @Override
public Mono<Object> resolveArgument(MethodParameter parameter, ModelMap model, ServerWebExchange exchange) { public Mono<Object> resolveArgument(MethodParameter parameter, BindingContext bindingContext,
ServerWebExchange exchange) {
Class<?> paramType = parameter.getParameterType(); Class<?> paramType = parameter.getParameterType();
MultiValueMap<String, String> queryParams = exchange.getRequest().getQueryParams(); MultiValueMap<String, String> queryParams = exchange.getRequest().getQueryParams();
if (MultiValueMap.class.isAssignableFrom(paramType)) { if (MultiValueMap.class.isAssignableFrom(paramType)) {

View File

@ -21,7 +21,7 @@ import org.springframework.core.MethodParameter;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.ui.ModelMap; import org.springframework.web.reactive.result.method.BindingContext;
import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver; import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebSession; import org.springframework.web.server.WebSession;
@ -52,7 +52,9 @@ public class ServerWebExchangeArgumentResolver implements HandlerMethodArgumentR
} }
@Override @Override
public Mono<Object> resolveArgument(MethodParameter parameter, ModelMap model, ServerWebExchange exchange) { public Mono<Object> resolveArgument(MethodParameter parameter, BindingContext bindingContext,
ServerWebExchange exchange) {
Class<?> paramType = parameter.getParameterType(); Class<?> paramType = parameter.getParameterType();
if (ServerWebExchange.class.isAssignableFrom(paramType)) { if (ServerWebExchange.class.isAssignableFrom(paramType)) {
return Mono.just(exchange); return Mono.just(exchange);

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

View File

@ -35,13 +35,11 @@ import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType; 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.MockServerHttpRequest;
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse; import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.tests.TestSubscriber; import org.springframework.tests.TestSubscriber;
import org.springframework.ui.ExtendedModelMap;
import org.springframework.ui.ModelMap;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.PutMapping;
@ -376,8 +374,9 @@ public class RequestMappingInfoHandlerMappingTests {
ServerWebExchange exchange = createExchange(HttpMethod.OPTIONS, requestURI); ServerWebExchange exchange = createExchange(HttpMethod.OPTIONS, requestURI);
HandlerMethod handlerMethod = (HandlerMethod) this.handlerMapping.getHandler(exchange).block(); HandlerMethod handlerMethod = (HandlerMethod) this.handlerMapping.getHandler(exchange).block();
ModelMap model = new ExtendedModelMap(); BindingContext bindingContext = new BindingContext();
Mono<HandlerResult> mono = new InvocableHandlerMethod(handlerMethod).invokeForRequest(exchange, model); InvocableHandlerMethod invocable = new InvocableHandlerMethod(handlerMethod);
Mono<HandlerResult> mono = invocable.invokeForRequest(exchange, bindingContext);
HandlerResult result = mono.block(); HandlerResult result = mono.block();
assertNotNull(result); 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.http.server.reactive.ServerHttpRequest;
import org.springframework.tests.TestSubscriber; import org.springframework.tests.TestSubscriber;
import org.springframework.web.bind.annotation.CookieValue; 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.ServerWebExchange;
import org.springframework.web.server.ServerWebInputException; import org.springframework.web.server.ServerWebInputException;
import org.springframework.web.server.adapter.DefaultServerWebExchange; import org.springframework.web.server.adapter.DefaultServerWebExchange;
@ -59,6 +60,8 @@ public class CookieValueMethodArgumentResolverTests {
private MethodParameter cookieStringParameter; private MethodParameter cookieStringParameter;
private MethodParameter stringParameter; private MethodParameter stringParameter;
private BindingContext bindingContext = new BindingContext();
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
@ -90,7 +93,9 @@ public class CookieValueMethodArgumentResolverTests {
HttpCookie expected = new HttpCookie("name", "foo"); HttpCookie expected = new HttpCookie("name", "foo");
this.exchange.getRequest().getCookies().add(expected.getName(), expected); 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()); assertEquals(expected, mono.block());
} }
@ -99,14 +104,16 @@ public class CookieValueMethodArgumentResolverTests {
HttpCookie cookie = new HttpCookie("name", "foo"); HttpCookie cookie = new HttpCookie("name", "foo");
this.exchange.getRequest().getCookies().add(cookie.getName(), cookie); 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()); assertEquals("Invalid result", cookie.getValue(), mono.block());
} }
@Test @Test
public void resolveCookieDefaultValue() { public void resolveCookieDefaultValue() {
Mono<Object> mono = this.resolver.resolveArgument(this.cookieStringParameter, null, this.exchange); Object result = this.resolver.resolveArgument(
Object result = mono.block(); this.cookieStringParameter, this.bindingContext, this.exchange).block();
assertTrue(result instanceof String); assertTrue(result instanceof String);
assertEquals("bar", result); assertEquals("bar", result);
@ -114,7 +121,7 @@ public class CookieValueMethodArgumentResolverTests {
@Test @Test
public void notFound() { 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 TestSubscriber
.subscribe(mono) .subscribe(mono)
.assertError(ServerWebInputException.class); .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.MockServerHttpRequest;
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse; import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpRequest; 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.ServerWebExchange;
import org.springframework.web.server.adapter.DefaultServerWebExchange; import org.springframework.web.server.adapter.DefaultServerWebExchange;
import org.springframework.web.server.session.MockWebSessionManager; import org.springframework.web.server.session.MockWebSessionManager;
@ -82,7 +83,9 @@ public class ExpressionValueMethodArgumentResolverTests {
public void resolveSystemProperty() throws Exception { public void resolveSystemProperty() throws Exception {
System.setProperty("systemProperty", "22"); System.setProperty("systemProperty", "22");
try { 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(); Object value = mono.block();
assertEquals(22, value); 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.MockServerHttpRequest;
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse; import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
import org.springframework.tests.TestSubscriber; import org.springframework.tests.TestSubscriber;
import org.springframework.ui.ExtendedModelMap;
import org.springframework.validation.Validator; import org.springframework.validation.Validator;
import org.springframework.web.reactive.result.ResolvableMethod; 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.ServerWebExchange;
import org.springframework.web.server.ServerWebInputException; import org.springframework.web.server.ServerWebInputException;
import org.springframework.web.server.adapter.DefaultServerWebExchange; import org.springframework.web.server.adapter.DefaultServerWebExchange;
@ -304,7 +304,7 @@ public class HttpEntityArgumentResolverTests {
this.request.setBody(body); this.request.setBody(body);
MethodParameter param = this.testMethod.resolveParam(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);
Object value = result.block(Duration.ofSeconds(5)); Object value = result.block(Duration.ofSeconds(5));
assertNotNull(value); assertNotNull(value);
@ -317,7 +317,7 @@ public class HttpEntityArgumentResolverTests {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private <T> HttpEntity<T> resolveValueWithEmptyBody(ResolvableType type) { private <T> HttpEntity<T> resolveValueWithEmptyBody(ResolvableType type) {
MethodParameter param = this.testMethod.resolveParam(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)); HttpEntity<String> httpEntity = (HttpEntity<String>) result.block(Duration.ofSeconds(5));
assertEquals(this.request.getHeaders(), httpEntity.getHeaders()); 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.io.Serializable;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.time.Duration; import java.time.Duration;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -41,8 +39,6 @@ import rx.Single;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
import org.springframework.core.ResolvableType; import org.springframework.core.ResolvableType;
import org.springframework.core.codec.Decoder; 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.HttpMethod;
import org.springframework.http.codec.DecoderHttpMessageReader; import org.springframework.http.codec.DecoderHttpMessageReader;
import org.springframework.http.codec.HttpMessageReader; 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.adapter.DefaultServerWebExchange;
import org.springframework.web.server.session.MockWebSessionManager; import org.springframework.web.server.session.MockWebSessionManager;
import static org.junit.Assert.*; import static org.junit.Assert.assertArrayEquals;
import static org.springframework.core.ResolvableType.*; 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}. * Unit tests for {@link AbstractMessageReaderArgumentResolver}.
@ -302,12 +302,6 @@ public class MessageReaderArgumentResolverTests {
return new AbstractMessageReaderArgumentResolver(readers, new TestBeanValidator()) {}; 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") @SuppressWarnings("unused")
private void handle( private void handle(

View File

@ -27,12 +27,12 @@ import reactor.core.publisher.Mono;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
import org.springframework.http.HttpMethod; 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.MockServerHttpRequest;
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse; 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.bind.annotation.PathVariable;
import org.springframework.web.reactive.HandlerMapping; 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.ServerWebExchange;
import org.springframework.web.server.adapter.DefaultServerWebExchange; import org.springframework.web.server.adapter.DefaultServerWebExchange;
import org.springframework.web.server.session.MockWebSessionManager; import org.springframework.web.server.session.MockWebSessionManager;
@ -86,7 +86,7 @@ public class PathVariableMapMethodArgumentResolverTests {
uriTemplateVars.put("name2", "value2"); uriTemplateVars.put("name2", "value2");
this.exchange.getAttributes().put(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVars); 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(); Object result = mono.block();
assertEquals(uriTemplateVars, result); assertEquals(uriTemplateVars, result);
@ -94,7 +94,7 @@ public class PathVariableMapMethodArgumentResolverTests {
@Test @Test
public void resolveArgumentNoUriVars() throws Exception { 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(); Object result = mono.block();
assertEquals(Collections.emptyMap(), result); 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.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.http.HttpMethod; 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.MockServerHttpRequest;
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse; import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.tests.TestSubscriber; import org.springframework.tests.TestSubscriber;
import org.springframework.ui.ModelMap;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.reactive.HandlerMapping; 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.ServerErrorException;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.adapter.DefaultServerWebExchange; import org.springframework.web.server.adapter.DefaultServerWebExchange;
@ -98,7 +98,8 @@ public class PathVariableMethodArgumentResolverTests {
uriTemplateVars.put("name", "value"); uriTemplateVars.put("name", "value");
this.exchange.getAttributes().put(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVars); 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(); Object result = mono.block();
assertEquals("value", result); assertEquals("value", result);
} }
@ -109,7 +110,8 @@ public class PathVariableMethodArgumentResolverTests {
uriTemplateVars.put("name", "value"); uriTemplateVars.put("name", "value");
this.exchange.getAttributes().put(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVars); 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(); Object result = mono.block();
assertEquals("value", result); assertEquals("value", result);
} }
@ -120,14 +122,16 @@ public class PathVariableMethodArgumentResolverTests {
uriTemplateVars.put("name", "value"); uriTemplateVars.put("name", "value");
this.exchange.getAttributes().put(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVars); 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(); Object result = mono.block();
assertEquals(Optional.of("value"), result); assertEquals(Optional.of("value"), result);
} }
@Test @Test
public void handleMissingValue() throws Exception { 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 TestSubscriber
.subscribe(mono) .subscribe(mono)
.assertError(ServerErrorException.class); .assertError(ServerErrorException.class);
@ -135,7 +139,8 @@ public class PathVariableMethodArgumentResolverTests {
@Test @Test
public void nullIfNotRequired() throws Exception { 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 TestSubscriber
.subscribe(mono) .subscribe(mono)
.assertComplete() .assertComplete()
@ -144,7 +149,8 @@ public class PathVariableMethodArgumentResolverTests {
@Test @Test
public void wrapEmptyWithOptional() throws Exception { 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(); Object result = mono.block();
TestSubscriber TestSubscriber
.subscribe(mono) .subscribe(mono)

View File

@ -36,6 +36,7 @@ import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.tests.TestSubscriber; import org.springframework.tests.TestSubscriber;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.annotation.RequestAttribute; 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.ServerWebExchange;
import org.springframework.web.server.ServerWebInputException; import org.springframework.web.server.ServerWebInputException;
import org.springframework.web.server.adapter.DefaultServerWebExchange; import org.springframework.web.server.adapter.DefaultServerWebExchange;
@ -88,14 +89,14 @@ public class RequestAttributeMethodArgumentResolverTests {
@Test @Test
public void resolve() throws Exception { public void resolve() throws Exception {
MethodParameter param = initMethodParameter(0); 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 TestSubscriber
.subscribe(mono) .subscribe(mono)
.assertError(ServerWebInputException.class); .assertError(ServerWebInputException.class);
Foo foo = new Foo(); Foo foo = new Foo();
this.exchange.getAttributes().put("foo", 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()); assertSame(foo, mono.block());
} }
@ -104,33 +105,34 @@ public class RequestAttributeMethodArgumentResolverTests {
MethodParameter param = initMethodParameter(1); MethodParameter param = initMethodParameter(1);
Foo foo = new Foo(); Foo foo = new Foo();
this.exchange.getAttributes().put("specialFoo", 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()); assertSame(foo, mono.block());
} }
@Test @Test
public void resolveNotRequired() throws Exception { public void resolveNotRequired() throws Exception {
MethodParameter param = initMethodParameter(2); 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()); assertNull(mono.block());
Foo foo = new Foo(); Foo foo = new Foo();
this.exchange.getAttributes().put("foo", 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()); assertSame(foo, mono.block());
} }
@Test @Test
public void resolveOptional() throws Exception { public void resolveOptional() throws Exception {
MethodParameter param = initMethodParameter(3); 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()); assertNotNull(mono.block());
assertEquals(Optional.class, mono.block().getClass()); assertEquals(Optional.class, mono.block().getClass());
assertFalse(((Optional) mono.block()).isPresent()); assertFalse(((Optional) mono.block()).isPresent());
Foo foo = new Foo(); Foo foo = new Foo();
this.exchange.getAttributes().put("foo", 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()); assertNotNull(mono.block());
assertEquals(Optional.class, mono.block().getClass()); 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.MockServerHttpRequest;
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse; import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
import org.springframework.tests.TestSubscriber; import org.springframework.tests.TestSubscriber;
import org.springframework.ui.ExtendedModelMap;
import org.springframework.validation.Validator; import org.springframework.validation.Validator;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.reactive.result.ResolvableMethod; 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.ServerWebExchange;
import org.springframework.web.server.ServerWebInputException; import org.springframework.web.server.ServerWebInputException;
import org.springframework.web.server.adapter.DefaultServerWebExchange; import org.springframework.web.server.adapter.DefaultServerWebExchange;
@ -213,7 +213,7 @@ public class RequestBodyArgumentResolverTests {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private <T> T resolveValueWithEmptyBody(ResolvableType bodyType, boolean isRequired) { private <T> T resolveValueWithEmptyBody(ResolvableType bodyType, boolean isRequired) {
MethodParameter param = this.testMethod.resolveParam(bodyType, requestBody(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)); Object value = result.block(Duration.ofSeconds(5));
if (value != null) { if (value != null) {

View File

@ -39,6 +39,7 @@ import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.tests.TestSubscriber; import org.springframework.tests.TestSubscriber;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.annotation.RequestHeader; 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.ServerWebExchange;
import org.springframework.web.server.ServerWebInputException; import org.springframework.web.server.ServerWebInputException;
import org.springframework.web.server.adapter.DefaultServerWebExchange; import org.springframework.web.server.adapter.DefaultServerWebExchange;
@ -70,6 +71,8 @@ public class RequestHeaderMethodArgumentResolverTests {
private ServerWebExchange exchange; private ServerWebExchange exchange;
private BindingContext bindingContext = new BindingContext();
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
@ -107,7 +110,9 @@ public class RequestHeaderMethodArgumentResolverTests {
String expected = "foo"; String expected = "foo";
this.exchange.getRequest().getHeaders().add("name", expected); 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(); Object result = mono.block();
assertTrue(result instanceof String); assertTrue(result instanceof String);
assertEquals(expected, result); assertEquals(expected, result);
@ -118,7 +123,9 @@ public class RequestHeaderMethodArgumentResolverTests {
String[] expected = new String[] {"foo", "bar"}; String[] expected = new String[] {"foo", "bar"};
this.exchange.getRequest().getHeaders().put("name", Arrays.asList(expected)); 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(); Object result = mono.block();
assertTrue(result instanceof String[]); assertTrue(result instanceof String[]);
assertArrayEquals(expected, (String[]) result); assertArrayEquals(expected, (String[]) result);
@ -126,7 +133,9 @@ public class RequestHeaderMethodArgumentResolverTests {
@Test @Test
public void resolveDefaultValue() throws Exception { 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(); Object result = mono.block();
assertTrue(result instanceof String); assertTrue(result instanceof String);
assertEquals("bar", result); assertEquals("bar", result);
@ -136,7 +145,9 @@ public class RequestHeaderMethodArgumentResolverTests {
public void resolveDefaultValueFromSystemProperty() throws Exception { public void resolveDefaultValueFromSystemProperty() throws Exception {
System.setProperty("systemProperty", "bar"); System.setProperty("systemProperty", "bar");
try { 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(); Object result = mono.block();
assertTrue(result instanceof String); assertTrue(result instanceof String);
assertEquals("bar", result); assertEquals("bar", result);
@ -153,7 +164,9 @@ public class RequestHeaderMethodArgumentResolverTests {
System.setProperty("systemProperty", "bar"); System.setProperty("systemProperty", "bar");
try { 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(); Object result = mono.block();
assertTrue(result instanceof String); assertTrue(result instanceof String);
assertEquals(expected, result); assertEquals(expected, result);
@ -170,7 +183,9 @@ public class RequestHeaderMethodArgumentResolverTests {
System.setProperty("systemProperty", "bar"); System.setProperty("systemProperty", "bar");
try { 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(); Object result = mono.block();
assertTrue(result instanceof String); assertTrue(result instanceof String);
assertEquals(expected, result); assertEquals(expected, result);
@ -182,7 +197,9 @@ public class RequestHeaderMethodArgumentResolverTests {
@Test @Test
public void notFound() throws Exception { 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 TestSubscriber
.subscribe(mono) .subscribe(mono)
.assertError(ServerWebInputException.class); .assertError(ServerWebInputException.class);
@ -194,7 +211,7 @@ public class RequestHeaderMethodArgumentResolverTests {
String rfc1123val = "Thu, 21 Apr 2016 17:11:08 +0100"; String rfc1123val = "Thu, 21 Apr 2016 17:11:08 +0100";
this.exchange.getRequest().getHeaders().add("name", rfc1123val); 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(); Object result = mono.block();
assertTrue(result instanceof Date); assertTrue(result instanceof Date);
@ -206,7 +223,7 @@ public class RequestHeaderMethodArgumentResolverTests {
String rfc1123val = "Thu, 21 Apr 2016 17:11:08 +0100"; String rfc1123val = "Thu, 21 Apr 2016 17:11:08 +0100";
this.exchange.getRequest().getHeaders().add("name", rfc1123val); 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(); Object result = mono.block();
assertTrue(result instanceof Instant); 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.tests.TestSubscriber;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.annotation.RequestParam; 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.ServerWebExchange;
import org.springframework.web.server.ServerWebInputException; import org.springframework.web.server.ServerWebInputException;
import org.springframework.web.server.adapter.DefaultServerWebExchange; import org.springframework.web.server.adapter.DefaultServerWebExchange;
@ -71,6 +72,8 @@ public class RequestParamMethodArgumentResolverTests {
private MethodParameter paramNotRequired; private MethodParameter paramNotRequired;
private MethodParameter paramOptional; private MethodParameter paramOptional;
private BindingContext bindingContext = new BindingContext();
@Before @SuppressWarnings("ConfusingArgumentToVarargsMethod") @Before @SuppressWarnings("ConfusingArgumentToVarargsMethod")
public void setUp() throws Exception { public void setUp() throws Exception {
@ -117,9 +120,10 @@ public class RequestParamMethodArgumentResolverTests {
String expected = "foo"; String expected = "foo";
this.exchange.getRequest().getQueryParams().set("name", expected); this.exchange.getRequest().getQueryParams().set("name", expected);
Mono<Object> mono = this.resolver.resolveArgument(this.paramNamedDefaultValueString, null, this.exchange); Mono<Object> mono = this.resolver.resolveArgument(
Object result = mono.block(); this.paramNamedDefaultValueString, this.bindingContext, this.exchange);
Object result = mono.block();
assertTrue(result instanceof String); assertTrue(result instanceof String);
assertEquals("Invalid result", expected, result); assertEquals("Invalid result", expected, result);
} }
@ -129,25 +133,29 @@ public class RequestParamMethodArgumentResolverTests {
String[] expected = {"foo", "bar"}; String[] expected = {"foo", "bar"};
this.exchange.getRequest().getQueryParams().put("name", Arrays.asList(expected)); this.exchange.getRequest().getQueryParams().put("name", Arrays.asList(expected));
Mono<Object> mono = this.resolver.resolveArgument(this.paramNamedStringArray, null, this.exchange); Mono<Object> mono = this.resolver.resolveArgument(
Object result = mono.block(); this.paramNamedStringArray, this.bindingContext, this.exchange);
Object result = mono.block();
assertTrue(result instanceof String[]); assertTrue(result instanceof String[]);
assertArrayEquals(expected, (String[]) result); assertArrayEquals(expected, (String[]) result);
} }
@Test @Test
public void resolveDefaultValue() throws Exception { public void resolveDefaultValue() throws Exception {
Mono<Object> mono = this.resolver.resolveArgument(paramNamedDefaultValueString, null, this.exchange); Mono<Object> mono = this.resolver.resolveArgument(
Object result = mono.block(); this.paramNamedDefaultValueString, this.bindingContext, this.exchange);
Object result = mono.block();
assertTrue(result instanceof String); assertTrue(result instanceof String);
assertEquals("Invalid result", "bar", result); assertEquals("Invalid result", "bar", result);
} }
@Test @Test
public void missingRequestParam() throws Exception { 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 TestSubscriber
.subscribe(mono) .subscribe(mono)
.assertError(ServerWebInputException.class); .assertError(ServerWebInputException.class);
@ -156,57 +164,63 @@ public class RequestParamMethodArgumentResolverTests {
@Test @Test
public void resolveSimpleTypeParam() throws Exception { public void resolveSimpleTypeParam() throws Exception {
this.exchange.getRequest().getQueryParams().set("stringNotAnnot", "plainValue"); this.exchange.getRequest().getQueryParams().set("stringNotAnnot", "plainValue");
Mono<Object> mono = this.resolver.resolveArgument(paramStringNotAnnot, null, this.exchange); Mono<Object> mono = this.resolver.resolveArgument(
Object result = mono.block(); this.paramStringNotAnnot, this.bindingContext, this.exchange);
Object result = mono.block();
assertTrue(result instanceof String); assertTrue(result instanceof String);
assertEquals("plainValue", result); assertEquals("plainValue", result);
} }
@Test // SPR-8561 @Test // SPR-8561
public void resolveSimpleTypeParamToNull() throws Exception { public void resolveSimpleTypeParamToNull() throws Exception {
Mono<Object> mono = this.resolver.resolveArgument(paramStringNotAnnot, null, this.exchange); Mono<Object> mono = this.resolver.resolveArgument(
Object result = mono.block(); this.paramStringNotAnnot, this.bindingContext, this.exchange);
Object result = mono.block();
assertNull(result); assertNull(result);
} }
@Test // SPR-10180 @Test // SPR-10180
public void resolveEmptyValueToDefault() throws Exception { public void resolveEmptyValueToDefault() throws Exception {
this.exchange.getRequest().getQueryParams().set("name", ""); this.exchange.getRequest().getQueryParams().set("name", "");
Mono<Object> mono = this.resolver.resolveArgument(paramNamedDefaultValueString, null, this.exchange); Mono<Object> mono = this.resolver.resolveArgument(
Object result = mono.block(); this.paramNamedDefaultValueString, this.bindingContext, this.exchange);
Object result = mono.block();
assertEquals("bar", result); assertEquals("bar", result);
} }
@Test @Test
public void resolveEmptyValueWithoutDefault() throws Exception { public void resolveEmptyValueWithoutDefault() throws Exception {
this.exchange.getRequest().getQueryParams().set("stringNotAnnot", ""); this.exchange.getRequest().getQueryParams().set("stringNotAnnot", "");
Mono<Object> mono = this.resolver.resolveArgument(paramStringNotAnnot, null, this.exchange); Mono<Object> mono = this.resolver.resolveArgument(
Object result = mono.block(); this.paramStringNotAnnot, this.bindingContext, this.exchange);
Object result = mono.block();
assertEquals("", result); assertEquals("", result);
} }
@Test @Test
public void resolveEmptyValueRequiredWithoutDefault() throws Exception { public void resolveEmptyValueRequiredWithoutDefault() throws Exception {
this.exchange.getRequest().getQueryParams().set("name", ""); this.exchange.getRequest().getQueryParams().set("name", "");
Mono<Object> mono = this.resolver.resolveArgument(paramRequired, null, this.exchange); Mono<Object> mono = this.resolver.resolveArgument(
Object result = mono.block(); this.paramRequired, this.bindingContext, this.exchange);
Object result = mono.block();
assertEquals("", result); assertEquals("", result);
} }
@Test @Test
public void resolveOptionalParamValue() throws Exception { public void resolveOptionalParamValue() throws Exception {
Mono<Object> mono = this.resolver.resolveArgument(paramOptional, null, this.exchange); Mono<Object> mono = this.resolver.resolveArgument(
Object result = mono.block(); this.paramOptional, this.bindingContext, this.exchange);
Object result = mono.block();
assertEquals(Optional.empty(), result); assertEquals(Optional.empty(), result);
this.exchange.getRequest().getQueryParams().set("name", "123"); 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(); result = mono.block();
assertEquals(Optional.class, result.getClass()); assertEquals(Optional.class, result.getClass());

View File

@ -21,12 +21,12 @@ import reactor.core.publisher.Mono;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
import org.springframework.http.HttpMethod; 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.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse; 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.ResolvableMethod;
import org.springframework.web.reactive.result.method.BindingContext;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebSession; import org.springframework.web.server.WebSession;
import org.springframework.web.server.adapter.DefaultServerWebExchange; import org.springframework.web.server.adapter.DefaultServerWebExchange;
@ -84,7 +84,7 @@ public class ServerWebExchangeArgumentResolverTests {
} }
private void testResolveArgument(MethodParameter parameter, Object expected) { 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()); 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.tests.TestSubscriber;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.annotation.SessionAttribute; 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.ServerWebExchange;
import org.springframework.web.server.ServerWebInputException; import org.springframework.web.server.ServerWebInputException;
import org.springframework.web.server.WebSession; import org.springframework.web.server.WebSession;
@ -95,14 +96,14 @@ public class SessionAttributeMethodArgumentResolverTests {
@Test @Test
public void resolve() throws Exception { public void resolve() throws Exception {
MethodParameter param = initMethodParameter(0); 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 TestSubscriber
.subscribe(mono) .subscribe(mono)
.assertError(ServerWebInputException.class); .assertError(ServerWebInputException.class);
Foo foo = new Foo(); Foo foo = new Foo();
when(this.session.getAttribute("foo")).thenReturn(Optional.of(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()); assertSame(foo, mono.block());
} }
@ -111,33 +112,33 @@ public class SessionAttributeMethodArgumentResolverTests {
MethodParameter param = initMethodParameter(1); MethodParameter param = initMethodParameter(1);
Foo foo = new Foo(); Foo foo = new Foo();
when(this.session.getAttribute("specialFoo")).thenReturn(Optional.of(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()); assertSame(foo, mono.block());
} }
@Test @Test
public void resolveNotRequired() throws Exception { public void resolveNotRequired() throws Exception {
MethodParameter param = initMethodParameter(2); 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()); assertNull(mono.block());
Foo foo = new Foo(); Foo foo = new Foo();
when(this.session.getAttribute("foo")).thenReturn(Optional.of(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()); assertSame(foo, mono.block());
} }
@Test @Test
public void resolveOptional() throws Exception { public void resolveOptional() throws Exception {
MethodParameter param = initMethodParameter(3); 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()); assertNotNull(mono.block());
assertEquals(Optional.class, mono.block().getClass()); assertEquals(Optional.class, mono.block().getClass());
assertFalse(((Optional) mono.block()).isPresent()); assertFalse(((Optional) mono.block()).isPresent());
Foo foo = new Foo(); Foo foo = new Foo();
when(this.session.getAttribute("foo")).thenReturn(Optional.of(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()); assertNotNull(mono.block());
assertEquals(Optional.class, mono.block().getClass()); assertEquals(Optional.class, mono.block().getClass());