From 14997eccf3f07466d1ebf07c6bd2111a5f01d139 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 2 Feb 2016 14:30:05 -0500 Subject: [PATCH] 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. --- .../web/reactive/HandlerResult.java | 17 ++++++- .../handler/HttpHandlerHandlerAdapter.java | 5 ++- .../method/HandlerMethodArgumentResolver.java | 6 ++- .../method/InvocableHandlerMethod.java | 14 +++--- .../annotation/ModelArgumentResolver.java | 44 +++++++++++++++++++ .../RequestBodyArgumentResolver.java | 5 ++- .../RequestMappingHandlerAdapter.java | 12 +++-- .../RequestParamArgumentResolver.java | 3 +- .../SimpleHandlerResultHandlerTests.java | 29 +++++++----- .../method/InvocableHandlerMethodTests.java | 27 +++++++----- .../ResponseBodyResultHandlerTests.java | 7 +-- 11 files changed, 129 insertions(+), 40 deletions(-) create mode 100644 spring-web-reactive/src/main/java/org/springframework/web/reactive/method/annotation/ModelArgumentResolver.java diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/HandlerResult.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/HandlerResult.java index 69b21f9986b..28a691e3d5d 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/HandlerResult.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/HandlerResult.java @@ -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> 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 diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/handler/HttpHandlerHandlerAdapter.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/handler/HttpHandlerHandlerAdapter.java index bfe32fae984..67cc1fc2cc8 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/handler/HttpHandlerHandlerAdapter.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/handler/HttpHandlerHandlerAdapter.java @@ -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 handle(ServerWebExchange exchange, Object handler) { WebHandler webHandler = (WebHandler) handler; Mono 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)); } } diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/method/HandlerMethodArgumentResolver.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/method/HandlerMethodArgumentResolver.java index defc46ea649..2c2e7c0c72c 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/method/HandlerMethodArgumentResolver.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/method/HandlerMethodArgumentResolver.java @@ -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 resolveArgument(MethodParameter parameter, ServerWebExchange exchange); + Mono resolveArgument(MethodParameter parameter, ModelMap model, ServerWebExchange exchange); } diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/method/InvocableHandlerMethod.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/method/InvocableHandlerMethod.java index 47d84dfc6c6..860995a9624 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/method/InvocableHandlerMethod.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/method/InvocableHandlerMethod.java @@ -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 invokeForRequest(ServerWebExchange exchange, Object... providedArgs) { - return resolveArguments(exchange, providedArgs).then(args -> { + public Mono 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 resolveArguments(ServerWebExchange exchange, Object... providedArgs) { + private Mono 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"); diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/method/annotation/ModelArgumentResolver.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/method/annotation/ModelArgumentResolver.java new file mode 100644 index 00000000000..9365172f87e --- /dev/null +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/method/annotation/ModelArgumentResolver.java @@ -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 resolveArgument(MethodParameter parameter, ModelMap model, ServerWebExchange exchange) { + return Mono.just(model); + } + +} diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/method/annotation/RequestBodyArgumentResolver.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/method/annotation/RequestBodyArgumentResolver.java index d7bbf501490..c39aa0da503 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/method/annotation/RequestBodyArgumentResolver.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/method/annotation/RequestBodyArgumentResolver.java @@ -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 resolveArgument(MethodParameter parameter, ServerWebExchange exchange) { + public Mono resolveArgument(MethodParameter parameter, ModelMap model, + ServerWebExchange exchange) { + MediaType mediaType = exchange.getRequest().getHeaders().getContentType(); if (mediaType == null) { mediaType = MediaType.APPLICATION_OCTET_STREAM; diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/method/annotation/RequestMappingHandlerAdapter.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/method/annotation/RequestMappingHandlerAdapter.java index 9457a395fb6..5a81e4de7a9 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/method/annotation/RequestMappingHandlerAdapter.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/method/annotation/RequestMappingHandlerAdapter.java @@ -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, ExceptionHandlerMethodResolver> exceptionHandlerCache = - new ConcurrentHashMap, 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()) { diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/method/annotation/RequestParamArgumentResolver.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/method/annotation/RequestParamArgumentResolver.java index 0bbc40906f1..0d0dff9b2a3 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/method/annotation/RequestParamArgumentResolver.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/method/annotation/RequestParamArgumentResolver.java @@ -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 resolveArgument(MethodParameter param, ServerWebExchange exchange) { + public Mono 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(); diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/handler/SimpleHandlerResultHandlerTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/handler/SimpleHandlerResultHandlerTests.java index 9e6381c6727..907992e14db 100644 --- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/handler/SimpleHandlerResultHandlerTests.java +++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/handler/SimpleHandlerResultHandlerTests.java @@ -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()); } diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/method/InvocableHandlerMethodTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/method/InvocableHandlerMethodTests.java index 25273edf2f2..26e4c3ac36c 100644 --- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/method/InvocableHandlerMethodTests.java +++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/method/InvocableHandlerMethodTests.java @@ -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 publisher = hm.invokeForRequest(this.exchange); + Publisher publisher = hm.invokeForRequest(this.exchange, this.model); List 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 publisher = hm.invokeForRequest(this.exchange); + Publisher publisher = hm.invokeForRequest(this.exchange, this.model); List 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 publisher = hm.invokeForRequest(this.exchange); + Publisher publisher = hm.invokeForRequest(this.exchange, this.model); List 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 publisher = hm.invokeForRequest(this.exchange); + Publisher publisher = hm.invokeForRequest(this.exchange, this.model); List 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 publisher = hm.invokeForRequest(this.exchange); + Publisher 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 publisher = hm.invokeForRequest(this.exchange); + Publisher 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 publisher = hm.invokeForRequest(this.exchange); + Publisher 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 publisher = hm.invokeForRequest(this.exchange); + Publisher 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 publisher = hm.invokeForRequest(this.exchange); + Publisher 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 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)); } diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/method/annotation/ResponseBodyResultHandlerTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/method/annotation/ResponseBodyResultHandlerTests.java index 3fd05e77c23..b0e0b09c509 100644 --- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/method/annotation/ResponseBodyResultHandlerTests.java +++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/method/annotation/ResponseBodyResultHandlerTests.java @@ -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()))); }