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:
parent
cabb253269
commit
d87aa40efe
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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());
|
||||
|
|
Loading…
Reference in New Issue