提交 d87aa40e 编写于 作者: R Rossen Stoyanchev

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
上级 cabb2532
/*
* 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);
}
}
......@@ -19,11 +19,13 @@ package org.springframework.web.reactive.result.method;
import reactor.core.publisher.Mono;
import org.springframework.core.MethodParameter;
import org.springframework.ui.ModelMap;
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
* @since 5.0
*/
......@@ -37,9 +39,10 @@ public interface HandlerMethodArgumentResolver {
* does not resolve to any value, which will result in {@code null} passed
* as the argument value.
* @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
*/
Mono<Object> resolveArgument(MethodParameter parameter, ModelMap model, ServerWebExchange exchange);
Mono<Object> resolveArgument(MethodParameter parameter, BindingContext bindingContext,
ServerWebExchange exchange);
}
......@@ -81,18 +81,19 @@ public class InvocableHandlerMethod extends HandlerMethod {
/**
* Invoke the method and return a Publisher for the return value.
* @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
* (via {@code instanceof}) for resolving method arguments.
* @return Publisher that produces a single HandlerResult or an error signal;
* never throws an exception
*/
public Mono<HandlerResult> invokeForRequest(ServerWebExchange exchange, ModelMap model,
Object... providedArgs) {
public Mono<HandlerResult> invokeForRequest(ServerWebExchange exchange,
BindingContext bindingContext, Object... providedArgs) {
return resolveArguments(exchange, model, providedArgs).then(args -> {
return resolveArguments(exchange, bindingContext, providedArgs).then(args -> {
try {
Object value = doInvoke(args);
ModelMap model = bindingContext.getModel();
HandlerResult handlerResult = new HandlerResult(this, value, getReturnType(), model);
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())) {
return NO_ARGS;
}
......@@ -127,7 +130,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
.findFirst()
.orElseThrow(() -> getArgError("No resolver for ", param, null));
try {
return resolver.resolveArgument(param, model, exchange)
return resolver.resolveArgument(param, bindingContext, exchange)
.defaultIfEmpty(NO_VALUE)
.doOnError(cause -> {
if(logger.isDebugEnabled()) {
......
......@@ -32,6 +32,7 @@ import org.springframework.core.convert.ConversionService;
import org.springframework.ui.ModelMap;
import org.springframework.util.Assert;
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.server.ServerErrorException;
import org.springframework.web.server.ServerWebExchange;
......@@ -85,7 +86,9 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
@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);
MethodParameter nestedParameter = parameter.nestedIfOptional();
......@@ -95,6 +98,8 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
"Specified name must not resolve to null: [" + namedValueInfo.name + "]"));
}
ModelMap model = bindingContext.getModel();
return resolveName(resolvedName.toString(), nestedParameter, exchange)
.map(arg -> {
if ("".equals(arg) && namedValueInfo.defaultValue != null) {
......
......@@ -27,8 +27,8 @@ import org.springframework.http.HttpHeaders;
import org.springframework.http.RequestEntity;
import org.springframework.http.codec.HttpMessageReader;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.ui.ModelMap;
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.server.ServerWebExchange;
......@@ -73,7 +73,8 @@ public class HttpEntityArgumentResolver extends AbstractMessageReaderArgumentRes
}
@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);
MethodParameter bodyParameter = new MethodParameter(param);
......
......@@ -19,7 +19,7 @@ import reactor.core.publisher.Mono;
import org.springframework.core.MethodParameter;
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.server.ServerWebExchange;
......@@ -38,8 +38,10 @@ public class ModelArgumentResolver implements HandlerMethodArgumentResolver {
}
@Override
public Mono<Object> resolveArgument(MethodParameter parameter, ModelMap model, ServerWebExchange exchange) {
return Mono.just(model);
public Mono<Object> resolveArgument(MethodParameter parameter, BindingContext bindingContext,
ServerWebExchange exchange) {
return Mono.just(bindingContext.getModel());
}
}
......@@ -23,10 +23,10 @@ import java.util.Optional;
import reactor.core.publisher.Mono;
import org.springframework.core.MethodParameter;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
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.reactive.result.method.HandlerMethodArgumentResolver;
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.
*/
@Override
public Mono<Object> resolveArgument(MethodParameter parameter, ModelMap model,
public Mono<Object> resolveArgument(MethodParameter parameter, BindingContext bindingContext,
ServerWebExchange exchange) {
String name = HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE;
......
......@@ -23,9 +23,9 @@ import reactor.core.publisher.Mono;
import org.springframework.core.MethodParameter;
import org.springframework.core.ReactiveAdapterRegistry;
import org.springframework.http.codec.HttpMessageReader;
import org.springframework.ui.ModelMap;
import org.springframework.validation.Validator;
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.server.ServerWebExchange;
import org.springframework.web.server.ServerWebInputException;
......@@ -76,7 +76,9 @@ public class RequestBodyArgumentResolver extends AbstractMessageReaderArgumentRe
}
@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();
return readBody(param, isRequired, exchange);
}
......
......@@ -22,9 +22,9 @@ import reactor.core.publisher.Mono;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.ui.ModelMap;
import org.springframework.util.MultiValueMap;
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.server.ServerWebExchange;
......@@ -50,7 +50,9 @@ public class RequestHeaderMapMethodArgumentResolver implements HandlerMethodArgu
}
@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();
if (MultiValueMap.class.isAssignableFrom(parameter.getParameterType())) {
return Mono.just(headers);
......
......@@ -38,14 +38,13 @@ import org.springframework.core.convert.ConversionService;
import org.springframework.format.support.DefaultFormattingConversionService;
import org.springframework.http.codec.DecoderHttpMessageReader;
import org.springframework.http.codec.HttpMessageReader;
import org.springframework.ui.ExtendedModelMap;
import org.springframework.ui.ModelMap;
import org.springframework.validation.Validator;
import org.springframework.web.bind.support.WebBindingInitializer;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.method.annotation.ExceptionHandlerMethodResolver;
import org.springframework.web.reactive.HandlerAdapter;
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.InvocableHandlerMethod;
import org.springframework.web.server.ServerWebExchange;
......@@ -257,14 +256,16 @@ public class RequestMappingHandlerAdapter implements HandlerAdapter, BeanFactory
HandlerMethod handlerMethod = (HandlerMethod) handler;
InvocableHandlerMethod invocable = new InvocableHandlerMethod(handlerMethod);
invocable.setHandlerMethodArgumentResolvers(getArgumentResolvers());
ModelMap model = new ExtendedModelMap();
return invocable.invokeForRequest(exchange, model)
.map(result -> result.setExceptionHandler(ex -> handleException(ex, handlerMethod, exchange)))
.otherwise(ex -> handleException(ex, handlerMethod, exchange));
BindingContext bindingContext = new BindingContext(getWebBindingInitializer());
return invocable.invokeForRequest(exchange, bindingContext)
.map(result -> result.setExceptionHandler(
ex -> handleException(ex, handlerMethod, bindingContext, exchange)))
.otherwise(ex -> handleException(
ex, handlerMethod, bindingContext, exchange));
}
private Mono<HandlerResult> handleException(Throwable ex, HandlerMethod handlerMethod,
ServerWebExchange exchange) {
BindingContext bindingContext, ServerWebExchange exchange) {
if (ex instanceof Exception) {
InvocableHandlerMethod invocable = findExceptionHandler(handlerMethod, (Exception) ex);
......@@ -274,8 +275,8 @@ public class RequestMappingHandlerAdapter implements HandlerAdapter, BeanFactory
logger.debug("Invoking @ExceptionHandler method: " + invocable);
}
invocable.setHandlerMethodArgumentResolvers(getArgumentResolvers());
ExtendedModelMap errorModel = new ExtendedModelMap();
return invocable.invokeForRequest(exchange, errorModel, ex);
bindingContext.getModel().clear();
return invocable.invokeForRequest(exchange, bindingContext, ex);
}
catch (Exception invocationEx) {
if (logger.isErrorEnabled()) {
......
......@@ -21,10 +21,10 @@ import java.util.Map;
import reactor.core.publisher.Mono;
import org.springframework.core.MethodParameter;
import org.springframework.ui.ModelMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
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.server.ServerWebExchange;
......@@ -57,7 +57,9 @@ public class RequestParamMapMethodArgumentResolver implements HandlerMethodArgum
}
@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();
MultiValueMap<String, String> queryParams = exchange.getRequest().getQueryParams();
if (MultiValueMap.class.isAssignableFrom(paramType)) {
......
......@@ -21,7 +21,7 @@ import org.springframework.core.MethodParameter;
import org.springframework.http.HttpMethod;
import org.springframework.http.server.reactive.ServerHttpRequest;
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.server.ServerWebExchange;
import org.springframework.web.server.WebSession;
......@@ -52,7 +52,9 @@ public class ServerWebExchangeArgumentResolver implements HandlerMethodArgumentR
}
@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();
if (ServerWebExchange.class.isAssignableFrom(paramType)) {
return Mono.just(exchange);
......
......@@ -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)
......
......@@ -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);
......
......@@ -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);
......
......@@ -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);
}
......
......@@ -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());
......
......@@ -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(
......
......@@ -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);
......
......@@ -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)
......
......@@ -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());
......
......@@ -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) {
......
......@@ -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);
......
......@@ -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());
......
......@@ -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());
}
......
......@@ -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());
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册