diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/AbstractHandlerResultHandler.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/HandlerResultHandlerSupport.java similarity index 91% rename from spring-webflux/src/main/java/org/springframework/web/reactive/result/AbstractHandlerResultHandler.java rename to spring-webflux/src/main/java/org/springframework/web/reactive/result/HandlerResultHandlerSupport.java index 9075733ebb..eac05c35d2 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/AbstractHandlerResultHandler.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/HandlerResultHandlerSupport.java @@ -36,12 +36,13 @@ import org.springframework.web.server.ServerWebExchange; /** * Base class for {@link org.springframework.web.reactive.HandlerResultHandler - * HandlerResultHandler} implementations that perform content negotiation. + * HandlerResultHandler} with support for content negotiation and access to a + * {@code ReactiveAdapter} registry. * * @author Rossen Stoyanchev * @since 5.0 */ -public abstract class AbstractHandlerResultHandler implements Ordered { +public abstract class HandlerResultHandlerSupport implements Ordered { private static final MediaType MEDIA_TYPE_APPLICATION_ALL = new MediaType("application"); @@ -53,11 +54,11 @@ public abstract class AbstractHandlerResultHandler implements Ordered { private int order = LOWEST_PRECEDENCE; - protected AbstractHandlerResultHandler(RequestedContentTypeResolver contentTypeResolver) { + protected HandlerResultHandlerSupport(RequestedContentTypeResolver contentTypeResolver) { this(contentTypeResolver, new ReactiveAdapterRegistry()); } - protected AbstractHandlerResultHandler(RequestedContentTypeResolver contentTypeResolver, + protected HandlerResultHandlerSupport(RequestedContentTypeResolver contentTypeResolver, ReactiveAdapterRegistry adapterRegistry) { Assert.notNull(contentTypeResolver, "'contentTypeResolver' is required."); @@ -74,14 +75,6 @@ public abstract class AbstractHandlerResultHandler implements Ordered { return this.adapterRegistry; } - /** - * Shortcut to get a ReactiveAdapter for the top-level return value type. - */ - protected ReactiveAdapter getAdapter(HandlerResult result) { - Class returnType = result.getReturnType().getRawClass(); - return getAdapterRegistry().getAdapter(returnType, result.getReturnValue()); - } - /** * Return the configured {@link RequestedContentTypeResolver}. */ @@ -105,6 +98,15 @@ public abstract class AbstractHandlerResultHandler implements Ordered { } + /** + * Get a {@code ReactiveAdapter} for the top-level return value type. + * @return the matching adapter or {@code null} + */ + protected ReactiveAdapter getAdapter(HandlerResult result) { + Class returnType = result.getReturnType().getRawClass(); + return getAdapterRegistry().getAdapter(returnType, result.getReturnValue()); + } + /** * Select the best media type for the current request through a content * negotiation algorithm. diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageWriterResultHandler.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageWriterResultHandler.java index 5017f0f901..74bab5f0d2 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageWriterResultHandler.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageWriterResultHandler.java @@ -33,7 +33,7 @@ import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.util.Assert; import org.springframework.web.reactive.accept.RequestedContentTypeResolver; -import org.springframework.web.reactive.result.AbstractHandlerResultHandler; +import org.springframework.web.reactive.result.HandlerResultHandlerSupport; import org.springframework.web.server.NotAcceptableStatusException; import org.springframework.web.server.ServerWebExchange; @@ -44,7 +44,7 @@ import org.springframework.web.server.ServerWebExchange; * @author Rossen Stoyanchev * @since 5.0 */ -public abstract class AbstractMessageWriterResultHandler extends AbstractHandlerResultHandler { +public abstract class AbstractMessageWriterResultHandler extends HandlerResultHandlerSupport { private final List> messageWriters; diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolver.java index d482f691b0..a4e21ae043 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolver.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolver.java @@ -110,7 +110,7 @@ public class ModelAttributeMethodArgumentResolver implements HandlerMethodArgume if (adapter.isNoValue() || adapter.isMultiValue()) { return false; } - clazz = ResolvableType.forMethodParameter(parameter).getGeneric(0).getRawClass(); + clazz = parameter.nested().getNestedParameterType(); } return !BeanUtils.isSimpleProperty(clazz); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java index 103247e4e5..51d53bed68 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java @@ -46,7 +46,7 @@ import org.springframework.web.reactive.BindingContext; import org.springframework.web.reactive.HandlerResult; import org.springframework.web.reactive.HandlerResultHandler; import org.springframework.web.reactive.accept.RequestedContentTypeResolver; -import org.springframework.web.reactive.result.AbstractHandlerResultHandler; +import org.springframework.web.reactive.result.HandlerResultHandlerSupport; import org.springframework.web.server.NotAcceptableStatusException; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.support.HttpRequestPathHelper; @@ -77,7 +77,7 @@ import org.springframework.web.server.support.HttpRequestPathHelper; * @author Rossen Stoyanchev * @since 5.0 */ -public class ViewResolutionResultHandler extends AbstractHandlerResultHandler +public class ViewResolutionResultHandler extends HandlerResultHandlerSupport implements HandlerResultHandler, Ordered { private static final Object NO_VALUE = new Object(); diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/HandlerResultHandlerTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/HandlerResultHandlerTests.java index 63b45ec893..575aae9239 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/HandlerResultHandlerTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/HandlerResultHandlerTests.java @@ -37,7 +37,7 @@ import static org.junit.Assert.*; import static org.springframework.http.MediaType.*; /** - * Unit tests for {@link AbstractHandlerResultHandler}. + * Unit tests for {@link HandlerResultHandlerSupport}. * @author Rossen Stoyanchev */ public class HandlerResultHandlerTests { @@ -112,7 +112,7 @@ public class HandlerResultHandlerTests { @SuppressWarnings("WeakerAccess") - private static class TestResultHandler extends AbstractHandlerResultHandler { + private static class TestResultHandler extends HandlerResultHandlerSupport { protected TestResultHandler() { this(new HeaderContentTypeResolver());