Add AsyncHandlerMethodReturnValueHandler
Before this change HandlerMethodReturnValueHandler's were invoked in a specific order (type-based, annotation-based, custom). However handlers that deal with asynchronous return value handling need to always be considered first. This affects custom handlers in particular since they are normally ordered last. This change introduces an AsyncHandlerMethodReturnValueHandler sub-interface with a single method to determine if the return value is asynchronous and if it is to look for a matching handler only among those that are of type AsyncHandlerMethodReturnValueHandler. Issue: SPR-13083
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -21,7 +21,7 @@ import org.springframework.core.MethodParameter;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.async.WebAsyncTask;
|
||||
import org.springframework.web.context.request.async.WebAsyncUtils;
|
||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
||||
import org.springframework.web.method.support.AsyncHandlerMethodReturnValueHandler;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
|
||||
/**
|
||||
@@ -30,7 +30,7 @@ import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.2
|
||||
*/
|
||||
public class AsyncTaskMethodReturnValueHandler implements HandlerMethodReturnValueHandler {
|
||||
public class AsyncTaskMethodReturnValueHandler implements AsyncHandlerMethodReturnValueHandler {
|
||||
|
||||
private final BeanFactory beanFactory;
|
||||
|
||||
@@ -45,6 +45,11 @@ public class AsyncTaskMethodReturnValueHandler implements HandlerMethodReturnVal
|
||||
return WebAsyncTask.class.isAssignableFrom(returnType.getParameterType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAsyncReturnValue(Object returnValue, MethodParameter returnType) {
|
||||
return (returnValue != null && returnValue instanceof WebAsyncTask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleReturnValue(Object returnValue, MethodParameter returnType,
|
||||
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -21,6 +21,7 @@ import java.util.concurrent.Callable;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.async.WebAsyncUtils;
|
||||
import org.springframework.web.method.support.AsyncHandlerMethodReturnValueHandler;
|
||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
|
||||
@@ -30,13 +31,18 @@ import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.2
|
||||
*/
|
||||
public class CallableMethodReturnValueHandler implements HandlerMethodReturnValueHandler {
|
||||
public class CallableMethodReturnValueHandler implements AsyncHandlerMethodReturnValueHandler {
|
||||
|
||||
@Override
|
||||
public boolean supportsReturnType(MethodParameter returnType) {
|
||||
return Callable.class.isAssignableFrom(returnType.getParameterType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAsyncReturnValue(Object returnValue, MethodParameter returnType) {
|
||||
return (returnValue != null && returnValue instanceof Callable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleReturnValue(Object returnValue, MethodParameter returnType,
|
||||
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.springframework.lang.UsesJava8;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.async.DeferredResult;
|
||||
import org.springframework.web.context.request.async.WebAsyncUtils;
|
||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
||||
import org.springframework.web.method.support.AsyncHandlerMethodReturnValueHandler;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
|
||||
/**
|
||||
@@ -36,13 +36,18 @@ import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
* @since 4.2
|
||||
*/
|
||||
@UsesJava8
|
||||
public class CompletionStageReturnValueHandler implements HandlerMethodReturnValueHandler {
|
||||
public class CompletionStageReturnValueHandler implements AsyncHandlerMethodReturnValueHandler {
|
||||
|
||||
@Override
|
||||
public boolean supportsReturnType(MethodParameter returnType) {
|
||||
return CompletionStage.class.isAssignableFrom(returnType.getParameterType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAsyncReturnValue(Object returnValue, MethodParameter returnType) {
|
||||
return (returnValue != null && returnValue instanceof CompletionStage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleReturnValue(Object returnValue, MethodParameter returnType,
|
||||
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
|
||||
@@ -70,7 +75,6 @@ public class CompletionStageReturnValueHandler implements HandlerMethodReturnVal
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -20,6 +20,7 @@ import org.springframework.core.MethodParameter;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.async.DeferredResult;
|
||||
import org.springframework.web.context.request.async.WebAsyncUtils;
|
||||
import org.springframework.web.method.support.AsyncHandlerMethodReturnValueHandler;
|
||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
|
||||
@@ -29,13 +30,18 @@ import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.2
|
||||
*/
|
||||
public class DeferredResultMethodReturnValueHandler implements HandlerMethodReturnValueHandler {
|
||||
public class DeferredResultMethodReturnValueHandler implements AsyncHandlerMethodReturnValueHandler {
|
||||
|
||||
@Override
|
||||
public boolean supportsReturnType(MethodParameter returnType) {
|
||||
return DeferredResult.class.isAssignableFrom(returnType.getParameterType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAsyncReturnValue(Object returnValue, MethodParameter returnType) {
|
||||
return (returnValue != null && returnValue instanceof DeferredResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleReturnValue(Object returnValue, MethodParameter returnType,
|
||||
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -22,7 +22,7 @@ import org.springframework.util.concurrent.ListenableFutureCallback;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.async.DeferredResult;
|
||||
import org.springframework.web.context.request.async.WebAsyncUtils;
|
||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
||||
import org.springframework.web.method.support.AsyncHandlerMethodReturnValueHandler;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
|
||||
/**
|
||||
@@ -32,13 +32,18 @@ import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.1
|
||||
*/
|
||||
public class ListenableFutureReturnValueHandler implements HandlerMethodReturnValueHandler {
|
||||
public class ListenableFutureReturnValueHandler implements AsyncHandlerMethodReturnValueHandler {
|
||||
|
||||
@Override
|
||||
public boolean supportsReturnType(MethodParameter returnType) {
|
||||
return ListenableFuture.class.isAssignableFrom(returnType.getParameterType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAsyncReturnValue(Object returnValue, MethodParameter returnType) {
|
||||
return (returnValue != null && returnValue instanceof ListenableFuture);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleReturnValue(Object returnValue, MethodParameter returnType,
|
||||
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
|
||||
|
||||
@@ -40,7 +40,7 @@ import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.async.DeferredResult;
|
||||
import org.springframework.web.context.request.async.WebAsyncUtils;
|
||||
import org.springframework.web.filter.ShallowEtagHeaderFilter;
|
||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
||||
import org.springframework.web.method.support.AsyncHandlerMethodReturnValueHandler;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
|
||||
/**
|
||||
@@ -50,7 +50,7 @@ import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.2
|
||||
*/
|
||||
public class ResponseBodyEmitterReturnValueHandler implements HandlerMethodReturnValueHandler {
|
||||
public class ResponseBodyEmitterReturnValueHandler implements AsyncHandlerMethodReturnValueHandler {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(ResponseBodyEmitterReturnValueHandler.class);
|
||||
|
||||
@@ -75,6 +75,20 @@ public class ResponseBodyEmitterReturnValueHandler implements HandlerMethodRetur
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAsyncReturnValue(Object returnValue, MethodParameter returnType) {
|
||||
if (returnValue != null) {
|
||||
if (returnValue instanceof ResponseBodyEmitter) {
|
||||
return true;
|
||||
}
|
||||
else if (returnValue instanceof ResponseEntity) {
|
||||
Object body = ((ResponseEntity) returnValue).getBody();
|
||||
return (body != null && body instanceof ResponseBodyEmitter);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleReturnValue(Object returnValue, MethodParameter returnType,
|
||||
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user