1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.web.servlet.mvc.method.annotation;
18
19 import org.springframework.core.MethodParameter;
20 import org.springframework.util.concurrent.ListenableFuture;
21 import org.springframework.util.concurrent.ListenableFutureCallback;
22 import org.springframework.web.context.request.NativeWebRequest;
23 import org.springframework.web.context.request.async.DeferredResult;
24 import org.springframework.web.context.request.async.WebAsyncUtils;
25 import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
26 import org.springframework.web.method.support.ModelAndViewContainer;
27
28
29
30
31
32
33
34
35 public class ListenableFutureReturnValueHandler implements HandlerMethodReturnValueHandler {
36
37 @Override
38 public boolean supportsReturnType(MethodParameter returnType) {
39 return ListenableFuture.class.isAssignableFrom(returnType.getParameterType());
40 }
41
42 @Override
43 public void handleReturnValue(Object returnValue, MethodParameter returnType,
44 ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
45
46 if (returnValue == null) {
47 mavContainer.setRequestHandled(true);
48 return;
49 }
50
51 final DeferredResult<Object> deferredResult = new DeferredResult<Object>();
52 WebAsyncUtils.getAsyncManager(webRequest).startDeferredResultProcessing(deferredResult, mavContainer);
53
54 ListenableFuture<?> future = (ListenableFuture<?>) returnValue;
55 future.addCallback(new ListenableFutureCallback<Object>() {
56 @Override
57 public void onSuccess(Object result) {
58 deferredResult.setResult(result);
59 }
60 @Override
61 public void onFailure(Throwable ex) {
62 deferredResult.setErrorResult(ex);
63 }
64 });
65 }
66
67 }