From 56903581d9e88894b2103208b4028df48e414b47 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 18 Jul 2017 17:09:24 +0200 Subject: [PATCH] ResponseEntity declared as Object in WebFlux controller Issue: SPR-15785 --- .../springframework/web/reactive/HandlerResult.java | 9 ++++++--- .../annotation/ResponseEntityResultHandler.java | 13 ++++++++++++- .../ResponseEntityResultHandlerTests.java | 11 +++++++++++ 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/HandlerResult.java b/spring-webflux/src/main/java/org/springframework/web/reactive/HandlerResult.java index d2e5130a38e..b88f7a7f859 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/HandlerResult.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/HandlerResult.java @@ -92,15 +92,18 @@ public class HandlerResult { } /** - * Return the type of the value returned from the handler. + * Return the type of the value returned from the handler -- e.g. the return + * type declared on a controller method's signature. Also see + * {@link #getReturnTypeSource()} to obtain the underlying + * {@link MethodParameter} for the return type. */ public ResolvableType getReturnType() { return this.returnType; } /** - * Return the {@link MethodParameter} from which - * {@link #getReturnType() returnType} was created. + * Return the {@link MethodParameter} from which {@link #getReturnType() + * returnType} was created. */ public MethodParameter getReturnTypeSource() { return (MethodParameter) this.returnType.getSource(); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandler.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandler.java index bc76dcec98d..016c56fe097 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandler.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandler.java @@ -80,7 +80,8 @@ public class ResponseEntityResultHandler extends AbstractMessageWriterResultHand @Override public boolean supports(HandlerResult result) { - if (isSupportedType(result.getReturnType().getRawClass())) { + Class valueType = resolveReturnValueType(result); + if (isSupportedType(valueType)) { return true; } ReactiveAdapter adapter = getAdapter(result); @@ -88,6 +89,16 @@ public class ResponseEntityResultHandler extends AbstractMessageWriterResultHand isSupportedType(result.getReturnType().getGeneric().resolve(Object.class)); } + @Nullable + private static Class resolveReturnValueType(HandlerResult result) { + Class valueType = result.getReturnType().getRawClass(); + Object value = result.getReturnValue(); + if ((valueType == null || valueType.equals(Object.class)) && value != null) { + valueType = value.getClass(); + } + return valueType; + } + private boolean isSupportedType(@Nullable Class clazz) { return (clazz != null && HttpEntity.class.isAssignableFrom(clazz) && !RequestEntity.class.isAssignableFrom(clazz)); diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandlerTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandlerTests.java index 948e696013a..bf6e74b697d 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandlerTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandlerTests.java @@ -120,6 +120,11 @@ public class ResponseEntityResultHandlerTests { returnType = on(TestController.class).resolveReturnType(CompletableFuture.class, entity(String.class)); assertTrue(this.resultHandler.supports(handlerResult(value, returnType))); + + // SPR-15785 + value = ResponseEntity.ok("testing"); + returnType = on(TestController.class).resolveReturnType(Object.class); + assertTrue(this.resultHandler.supports(handlerResult(value, returnType))); } @Test @@ -190,6 +195,9 @@ public class ResponseEntityResultHandlerTests { MethodParameter returnType = on(TestController.class).resolveReturnType(entity(String.class)); testHandle(returnValue, returnType); + returnType = on(TestController.class).resolveReturnType(Object.class); + testHandle(returnValue, returnType); + returnValue = Mono.just(ok("abc")); returnType = on(TestController.class).resolveReturnType(Mono.class, entity(String.class)); testHandle(returnValue, returnType); @@ -387,6 +395,9 @@ public class ResponseEntityResultHandlerTests { Mono> monoResponseEntityWildcard() { return null; } Flux fluxWildcard() { return null; } + + Object object() { return null; } + } }