Support Model as method argument and in HandlerResult
A model is created and passed to argument resolvers including a new ModelArgumentResolver. The model is then exposed for result handling as a field in HandlerResult.
This commit is contained in:
@@ -22,6 +22,8 @@ import java.util.function.Function;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.ui.ExtendedModelMap;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -37,6 +39,8 @@ public class HandlerResult {
|
||||
|
||||
private final ResolvableType returnValueType;
|
||||
|
||||
private final ModelMap model;
|
||||
|
||||
private Function<Throwable, Mono<HandlerResult>> exceptionHandler;
|
||||
|
||||
|
||||
@@ -45,13 +49,16 @@ public class HandlerResult {
|
||||
* @param handler the handler that handled the request
|
||||
* @param returnValue the return value from the handler possibly {@code null}
|
||||
* @param returnValueType the return value type
|
||||
* @param model the model used for request handling
|
||||
*/
|
||||
public HandlerResult(Object handler, Object returnValue, ResolvableType returnValueType) {
|
||||
public HandlerResult(Object handler, Object returnValue, ResolvableType returnValueType, ModelMap model) {
|
||||
Assert.notNull(handler, "'handler' is required");
|
||||
Assert.notNull(returnValueType, "'returnValueType' is required");
|
||||
Assert.notNull(model, "'model' is required");
|
||||
this.handler = handler;
|
||||
this.returnValue = Optional.ofNullable(returnValue);
|
||||
this.returnValueType = returnValueType;
|
||||
this.model = new ExtendedModelMap();
|
||||
}
|
||||
|
||||
|
||||
@@ -76,6 +83,14 @@ public class HandlerResult {
|
||||
return this.returnValueType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the model used during request handling with attributes that may be
|
||||
* used to render HTML templates with.
|
||||
*/
|
||||
public ModelMap getModel() {
|
||||
return this.model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure an exception handler that may be used to produce an alternative
|
||||
* result when result handling fails. Especially for an async return value
|
||||
|
||||
@@ -20,6 +20,8 @@ import org.reactivestreams.Publisher;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.ui.ExtendedModelMap;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.reactive.DispatcherHandler;
|
||||
import org.springframework.web.reactive.HandlerAdapter;
|
||||
import org.springframework.web.reactive.HandlerResult;
|
||||
@@ -48,7 +50,8 @@ public class HttpHandlerHandlerAdapter implements HandlerAdapter {
|
||||
public Mono<HandlerResult> handle(ServerWebExchange exchange, Object handler) {
|
||||
WebHandler webHandler = (WebHandler) handler;
|
||||
Mono<Void> completion = webHandler.handle(exchange);
|
||||
return Mono.just(new HandlerResult(webHandler, completion, PUBLISHER_VOID));
|
||||
ModelMap model = new ExtendedModelMap();
|
||||
return Mono.just(new HandlerResult(webHandler, completion, PUBLISHER_VOID, model));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.web.reactive.method;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
|
||||
@@ -34,7 +35,10 @@ public interface HandlerMethodArgumentResolver {
|
||||
* The returned {@link Mono} may produce one or zero values if the argument
|
||||
* 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 exchange the current exchange
|
||||
*/
|
||||
Mono<Object> resolveArgument(MethodParameter parameter, ServerWebExchange exchange);
|
||||
Mono<Object> resolveArgument(MethodParameter parameter, ModelMap model, ServerWebExchange exchange);
|
||||
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.springframework.core.GenericTypeResolver;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.ParameterNameDiscoverer;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
@@ -77,17 +78,20 @@ 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 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, Object... providedArgs) {
|
||||
return resolveArguments(exchange, providedArgs).then(args -> {
|
||||
public Mono<HandlerResult> invokeForRequest(ServerWebExchange exchange, ModelMap model,
|
||||
Object... providedArgs) {
|
||||
|
||||
return resolveArguments(exchange, model, providedArgs).then(args -> {
|
||||
try {
|
||||
Object value = doInvoke(args);
|
||||
ResolvableType type = ResolvableType.forMethodParameter(getReturnType());
|
||||
HandlerResult handlerResult = new HandlerResult(this, value, type);
|
||||
HandlerResult handlerResult = new HandlerResult(this, value, type, model);
|
||||
return Mono.just(handlerResult);
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
@@ -100,7 +104,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||
});
|
||||
}
|
||||
|
||||
private Mono<Object[]> resolveArguments(ServerWebExchange exchange, Object... providedArgs) {
|
||||
private Mono<Object[]> resolveArguments(ServerWebExchange exchange, ModelMap model, Object... providedArgs) {
|
||||
if (ObjectUtils.isEmpty(getMethodParameters())) {
|
||||
return NO_ARGS;
|
||||
}
|
||||
@@ -121,7 +125,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||
.findFirst()
|
||||
.orElseThrow(() -> getArgError("No resolver for ", param, null));
|
||||
try {
|
||||
return resolver.resolveArgument(param, exchange)
|
||||
return resolver.resolveArgument(param, model, exchange)
|
||||
.defaultIfEmpty(NO_VALUE)
|
||||
.otherwise(ex -> Mono.error(getArgError("Error resolving ", param, ex)))
|
||||
.log("reactor.unresolved");
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.method.annotation;
|
||||
|
||||
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.method.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
/**
|
||||
* Resolver for the {@link Model} controller method argument.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class ModelArgumentResolver implements HandlerMethodArgumentResolver {
|
||||
|
||||
|
||||
@Override
|
||||
public boolean supportsParameter(MethodParameter parameter) {
|
||||
return Model.class.isAssignableFrom(parameter.getParameterType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Object> resolveArgument(MethodParameter parameter, ModelMap model, ServerWebExchange exchange) {
|
||||
return Mono.just(model);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,6 +28,7 @@ import org.springframework.core.codec.Decoder;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.reactive.method.HandlerMethodArgumentResolver;
|
||||
@@ -58,7 +59,9 @@ public class RequestBodyArgumentResolver implements HandlerMethodArgumentResolve
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Object> resolveArgument(MethodParameter parameter, ServerWebExchange exchange) {
|
||||
public Mono<Object> resolveArgument(MethodParameter parameter, ModelMap model,
|
||||
ServerWebExchange exchange) {
|
||||
|
||||
MediaType mediaType = exchange.getRequest().getHeaders().getContentType();
|
||||
if (mediaType == null) {
|
||||
mediaType = MediaType.APPLICATION_OCTET_STREAM;
|
||||
|
||||
@@ -38,6 +38,8 @@ import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.core.io.buffer.DataBufferAllocator;
|
||||
import org.springframework.core.io.buffer.NettyDataBufferAllocator;
|
||||
import org.springframework.ui.ExtendedModelMap;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.method.annotation.ExceptionHandlerMethodResolver;
|
||||
@@ -64,7 +66,7 @@ public class RequestMappingHandlerAdapter implements HandlerAdapter, Initializin
|
||||
new NettyDataBufferAllocator(new UnpooledByteBufAllocator(false));
|
||||
|
||||
private final Map<Class<?>, ExceptionHandlerMethodResolver> exceptionHandlerCache =
|
||||
new ConcurrentHashMap<Class<?>, ExceptionHandlerMethodResolver>(64);
|
||||
new ConcurrentHashMap<>(64);
|
||||
|
||||
|
||||
/**
|
||||
@@ -105,6 +107,7 @@ public class RequestMappingHandlerAdapter implements HandlerAdapter, Initializin
|
||||
|
||||
this.argumentResolvers.add(new RequestParamArgumentResolver());
|
||||
this.argumentResolvers.add(new RequestBodyArgumentResolver(decoders, this.conversionService));
|
||||
this.argumentResolvers.add(new ModelArgumentResolver());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,8 +121,8 @@ public class RequestMappingHandlerAdapter implements HandlerAdapter, Initializin
|
||||
HandlerMethod handlerMethod = (HandlerMethod) handler;
|
||||
InvocableHandlerMethod invocable = new InvocableHandlerMethod(handlerMethod);
|
||||
invocable.setHandlerMethodArgumentResolvers(this.argumentResolvers);
|
||||
|
||||
return invocable.invokeForRequest(exchange)
|
||||
ModelMap model = new ExtendedModelMap();
|
||||
return invocable.invokeForRequest(exchange, model)
|
||||
.map(result -> result.setExceptionHandler(ex -> handleException(ex, handlerMethod, exchange)))
|
||||
.otherwise(ex -> handleException(ex, handlerMethod, exchange));
|
||||
}
|
||||
@@ -135,7 +138,8 @@ public class RequestMappingHandlerAdapter implements HandlerAdapter, Initializin
|
||||
logger.debug("Invoking @ExceptionHandler method: " + invocable);
|
||||
}
|
||||
invocable.setHandlerMethodArgumentResolvers(getArgumentResolvers());
|
||||
return invocable.invokeForRequest(exchange, ex);
|
||||
ExtendedModelMap errorModel = new ExtendedModelMap();
|
||||
return invocable.invokeForRequest(exchange, errorModel, ex);
|
||||
}
|
||||
catch (Exception invocationEx) {
|
||||
if (logger.isErrorEnabled()) {
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.web.reactive.method.annotation;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.reactive.method.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
@@ -41,7 +42,7 @@ public class RequestParamArgumentResolver implements HandlerMethodArgumentResolv
|
||||
|
||||
|
||||
@Override
|
||||
public Mono<Object> resolveArgument(MethodParameter param, ServerWebExchange exchange) {
|
||||
public Mono<Object> resolveArgument(MethodParameter param, ModelMap model, ServerWebExchange exchange) {
|
||||
RequestParam annotation = param.getParameterAnnotation(RequestParam.class);
|
||||
String name = (annotation.value().length() != 0 ? annotation.value() : param.getParameterName());
|
||||
UriComponents uriComponents = UriComponentsBuilder.fromUri(exchange.getRequest().getURI()).build();
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.springframework.core.convert.support.ReactiveStreamsToCompletableFutureConverter;
|
||||
import org.springframework.core.convert.support.ReactiveStreamsToReactorStreamConverter;
|
||||
import org.springframework.core.convert.support.ReactiveStreamsToRxJava1Converter;
|
||||
import org.springframework.ui.ExtendedModelMap;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.reactive.HandlerResult;
|
||||
|
||||
@@ -46,28 +47,28 @@ public class SimpleHandlerResultHandlerTests {
|
||||
|
||||
HandlerMethod hm = new HandlerMethod(controller, TestController.class.getMethod("voidReturnValue"));
|
||||
ResolvableType type = ResolvableType.forMethodParameter(hm.getReturnType());
|
||||
assertTrue(resultHandler.supports(new HandlerResult(hm, null, type)));
|
||||
assertTrue(resultHandler.supports(createHandlerResult(hm, type)));
|
||||
|
||||
hm = new HandlerMethod(controller, TestController.class.getMethod("publisherString"));
|
||||
type = ResolvableType.forMethodParameter(hm.getReturnType());
|
||||
assertFalse(resultHandler.supports(new HandlerResult(hm, null, type)));
|
||||
assertFalse(resultHandler.supports(createHandlerResult(hm, type)));
|
||||
|
||||
hm = new HandlerMethod(controller, TestController.class.getMethod("publisherVoid"));
|
||||
type = ResolvableType.forMethodParameter(hm.getReturnType());
|
||||
assertTrue(resultHandler.supports(new HandlerResult(hm, null, type)));
|
||||
assertTrue(resultHandler.supports(createHandlerResult(hm, type)));
|
||||
|
||||
hm = new HandlerMethod(controller, TestController.class.getMethod("streamVoid"));
|
||||
type = ResolvableType.forMethodParameter(hm.getReturnType());
|
||||
// Reactor Stream is a Publisher
|
||||
assertTrue(resultHandler.supports(new HandlerResult(hm, null, type)));
|
||||
assertTrue(resultHandler.supports(createHandlerResult(hm, type)));
|
||||
|
||||
hm = new HandlerMethod(controller, TestController.class.getMethod("observableVoid"));
|
||||
type = ResolvableType.forMethodParameter(hm.getReturnType());
|
||||
assertFalse(resultHandler.supports(new HandlerResult(hm, null, type)));
|
||||
assertFalse(resultHandler.supports(createHandlerResult(hm, type)));
|
||||
|
||||
hm = new HandlerMethod(controller, TestController.class.getMethod("completableFutureVoid"));
|
||||
type = ResolvableType.forMethodParameter(hm.getReturnType());
|
||||
assertFalse(resultHandler.supports(new HandlerResult(hm, null, type)));
|
||||
assertFalse(resultHandler.supports(createHandlerResult(hm, type)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -82,27 +83,31 @@ public class SimpleHandlerResultHandlerTests {
|
||||
|
||||
HandlerMethod hm = new HandlerMethod(controller, TestController.class.getMethod("voidReturnValue"));
|
||||
ResolvableType type = ResolvableType.forMethodParameter(hm.getReturnType());
|
||||
assertTrue(resultHandler.supports(new HandlerResult(hm, null, type)));
|
||||
assertTrue(resultHandler.supports(createHandlerResult(hm, type)));
|
||||
|
||||
hm = new HandlerMethod(controller, TestController.class.getMethod("publisherString"));
|
||||
type = ResolvableType.forMethodParameter(hm.getReturnType());
|
||||
assertFalse(resultHandler.supports(new HandlerResult(hm, null, type)));
|
||||
assertFalse(resultHandler.supports(createHandlerResult(hm, type)));
|
||||
|
||||
hm = new HandlerMethod(controller, TestController.class.getMethod("publisherVoid"));
|
||||
type = ResolvableType.forMethodParameter(hm.getReturnType());
|
||||
assertTrue(resultHandler.supports(new HandlerResult(hm, null, type)));
|
||||
assertTrue(resultHandler.supports(createHandlerResult(hm, type)));
|
||||
|
||||
hm = new HandlerMethod(controller, TestController.class.getMethod("streamVoid"));
|
||||
type = ResolvableType.forMethodParameter(hm.getReturnType());
|
||||
assertTrue(resultHandler.supports(new HandlerResult(hm, null, type)));
|
||||
assertTrue(resultHandler.supports(createHandlerResult(hm, type)));
|
||||
|
||||
hm = new HandlerMethod(controller, TestController.class.getMethod("observableVoid"));
|
||||
type = ResolvableType.forMethodParameter(hm.getReturnType());
|
||||
assertTrue(resultHandler.supports(new HandlerResult(hm, null, type)));
|
||||
assertTrue(resultHandler.supports(createHandlerResult(hm, type)));
|
||||
|
||||
hm = new HandlerMethod(controller, TestController.class.getMethod("completableFutureVoid"));
|
||||
type = ResolvableType.forMethodParameter(hm.getReturnType());
|
||||
assertTrue(resultHandler.supports(new HandlerResult(hm, null, type)));
|
||||
assertTrue(resultHandler.supports(createHandlerResult(hm, type)));
|
||||
}
|
||||
|
||||
private HandlerResult createHandlerResult(HandlerMethod hm, ResolvableType type) {
|
||||
return new HandlerResult(hm, null, type, new ExtendedModelMap());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -31,6 +31,8 @@ import reactor.rx.Stream;
|
||||
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
import org.springframework.ui.ExtendedModelMap;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.reactive.HandlerResult;
|
||||
@@ -54,12 +56,15 @@ public class InvocableHandlerMethodTests {
|
||||
|
||||
private ServerWebExchange exchange;
|
||||
|
||||
private ModelMap model;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
WebSessionManager sessionManager = mock(WebSessionManager.class);
|
||||
this.request = mock(ServerHttpRequest.class);
|
||||
this.exchange = new DefaultServerWebExchange(request, mock(ServerHttpResponse.class), sessionManager);
|
||||
this.model = new ExtendedModelMap();
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +72,7 @@ public class InvocableHandlerMethodTests {
|
||||
public void noArgsMethod() throws Exception {
|
||||
InvocableHandlerMethod hm = createHandlerMethod("noArgs");
|
||||
|
||||
Publisher<HandlerResult> publisher = hm.invokeForRequest(this.exchange);
|
||||
Publisher<HandlerResult> publisher = hm.invokeForRequest(this.exchange, this.model);
|
||||
List<HandlerResult> values = Stream.from(publisher).toList().get();
|
||||
|
||||
assertEquals(1, values.size());
|
||||
@@ -80,7 +85,7 @@ public class InvocableHandlerMethodTests {
|
||||
InvocableHandlerMethod hm = createHandlerMethod("singleArg", String.class);
|
||||
hm.setHandlerMethodArgumentResolvers(Collections.singletonList(new RequestParamArgumentResolver()));
|
||||
|
||||
Publisher<HandlerResult> publisher = hm.invokeForRequest(this.exchange);
|
||||
Publisher<HandlerResult> publisher = hm.invokeForRequest(this.exchange, this.model);
|
||||
List<HandlerResult> values = Stream.from(publisher).toList().get();
|
||||
|
||||
assertEquals(1, values.size());
|
||||
@@ -92,7 +97,7 @@ public class InvocableHandlerMethodTests {
|
||||
InvocableHandlerMethod hm = createHandlerMethod("singleArg", String.class);
|
||||
addResolver(hm, Mono.just("value1"));
|
||||
|
||||
Publisher<HandlerResult> publisher = hm.invokeForRequest(this.exchange);
|
||||
Publisher<HandlerResult> publisher = hm.invokeForRequest(this.exchange, this.model);
|
||||
List<HandlerResult> values = Stream.from(publisher).toList().get();
|
||||
|
||||
assertEquals(1, values.size());
|
||||
@@ -104,7 +109,7 @@ public class InvocableHandlerMethodTests {
|
||||
InvocableHandlerMethod hm = createHandlerMethod("singleArg", String.class);
|
||||
addResolver(hm, Flux.fromIterable(Arrays.asList("value1", "value2", "value3")));
|
||||
|
||||
Publisher<HandlerResult> publisher = hm.invokeForRequest(this.exchange);
|
||||
Publisher<HandlerResult> publisher = hm.invokeForRequest(this.exchange, this.model);
|
||||
List<HandlerResult> values = Stream.from(publisher).toList().get();
|
||||
|
||||
assertEquals(1, values.size());
|
||||
@@ -115,7 +120,7 @@ public class InvocableHandlerMethodTests {
|
||||
public void noResolverForArg() throws Exception {
|
||||
InvocableHandlerMethod hm = createHandlerMethod("singleArg", String.class);
|
||||
|
||||
Publisher<HandlerResult> publisher = hm.invokeForRequest(this.exchange);
|
||||
Publisher<HandlerResult> publisher = hm.invokeForRequest(this.exchange, this.model);
|
||||
Throwable ex = awaitErrorSignal(publisher);
|
||||
|
||||
assertEquals(IllegalStateException.class, ex.getClass());
|
||||
@@ -127,12 +132,12 @@ public class InvocableHandlerMethodTests {
|
||||
public void resolveArgumentWithThrownException() throws Exception {
|
||||
HandlerMethodArgumentResolver resolver = mock(HandlerMethodArgumentResolver.class);
|
||||
when(resolver.supportsParameter(any())).thenReturn(true);
|
||||
when(resolver.resolveArgument(any(), any())).thenThrow(new IllegalStateException("boo"));
|
||||
when(resolver.resolveArgument(any(), any(), any())).thenThrow(new IllegalStateException("boo"));
|
||||
|
||||
InvocableHandlerMethod hm = createHandlerMethod("singleArg", String.class);
|
||||
hm.setHandlerMethodArgumentResolvers(Collections.singletonList(resolver));
|
||||
|
||||
Publisher<HandlerResult> publisher = hm.invokeForRequest(this.exchange);
|
||||
Publisher<HandlerResult> publisher = hm.invokeForRequest(this.exchange, this.model);
|
||||
Throwable ex = awaitErrorSignal(publisher);
|
||||
|
||||
assertEquals(IllegalStateException.class, ex.getClass());
|
||||
@@ -146,7 +151,7 @@ public class InvocableHandlerMethodTests {
|
||||
InvocableHandlerMethod hm = createHandlerMethod("singleArg", String.class);
|
||||
addResolver(hm, Mono.error(new IllegalStateException("boo")));
|
||||
|
||||
Publisher<HandlerResult> publisher = hm.invokeForRequest(this.exchange);
|
||||
Publisher<HandlerResult> publisher = hm.invokeForRequest(this.exchange, this.model);
|
||||
Throwable ex = awaitErrorSignal(publisher);
|
||||
|
||||
assertEquals(IllegalStateException.class, ex.getClass());
|
||||
@@ -160,7 +165,7 @@ public class InvocableHandlerMethodTests {
|
||||
InvocableHandlerMethod hm = createHandlerMethod("singleArg", String.class);
|
||||
addResolver(hm, Mono.just(1));
|
||||
|
||||
Publisher<HandlerResult> publisher = hm.invokeForRequest(this.exchange);
|
||||
Publisher<HandlerResult> publisher = hm.invokeForRequest(this.exchange, this.model);
|
||||
Throwable ex = awaitErrorSignal(publisher);
|
||||
|
||||
assertEquals(IllegalStateException.class, ex.getClass());
|
||||
@@ -173,7 +178,7 @@ public class InvocableHandlerMethodTests {
|
||||
public void invocationTargetExceptionIsUnwrapped() throws Exception {
|
||||
InvocableHandlerMethod hm = createHandlerMethod("exceptionMethod");
|
||||
|
||||
Publisher<HandlerResult> publisher = hm.invokeForRequest(this.exchange);
|
||||
Publisher<HandlerResult> publisher = hm.invokeForRequest(this.exchange, this.model);
|
||||
Throwable ex = awaitErrorSignal(publisher);
|
||||
|
||||
assertEquals(IllegalStateException.class, ex.getClass());
|
||||
@@ -190,7 +195,7 @@ public class InvocableHandlerMethodTests {
|
||||
private void addResolver(InvocableHandlerMethod handlerMethod, Publisher<Object> resolvedValue) {
|
||||
HandlerMethodArgumentResolver resolver = mock(HandlerMethodArgumentResolver.class);
|
||||
when(resolver.supportsParameter(any())).thenReturn(true);
|
||||
when(resolver.resolveArgument(any(), any())).thenReturn(Mono.from(resolvedValue));
|
||||
when(resolver.resolveArgument(any(), any(), any())).thenReturn(Mono.from(resolvedValue));
|
||||
handlerMethod.setHandlerMethodArgumentResolvers(Collections.singletonList(resolver));
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.codec.support.StringEncoder;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.core.io.buffer.DefaultDataBufferAllocator;
|
||||
import org.springframework.ui.ExtendedModelMap;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.reactive.HandlerResult;
|
||||
@@ -47,15 +48,15 @@ public class ResponseBodyResultHandlerTests {
|
||||
|
||||
HandlerMethod hm = new HandlerMethod(controller,TestController.class.getMethod("notAnnotated"));
|
||||
ResolvableType type = ResolvableType.forMethodParameter(hm.getReturnType());
|
||||
assertFalse(handler.supports(new HandlerResult(hm, null, type)));
|
||||
assertFalse(handler.supports(new HandlerResult(hm, null, type, new ExtendedModelMap())));
|
||||
|
||||
hm = new HandlerMethod(controller, TestController.class.getMethod("publisherString"));
|
||||
type = ResolvableType.forMethodParameter(hm.getReturnType());
|
||||
assertTrue(handler.supports(new HandlerResult(hm, null, type)));
|
||||
assertTrue(handler.supports(new HandlerResult(hm, null, type, new ExtendedModelMap())));
|
||||
|
||||
hm = new HandlerMethod(controller, TestController.class.getMethod("publisherVoid"));
|
||||
type = ResolvableType.forMethodParameter(hm.getReturnType());
|
||||
assertTrue(handler.supports(new HandlerResult(hm, null, type)));
|
||||
assertTrue(handler.supports(new HandlerResult(hm, null, type, new ExtendedModelMap())));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user