Fix issue with async return value type determination

Before this change, the type of asynchronously produced return values
(e.g. Callable, DeferredResult, ListenableFuture) could not be
properly determined with an actual resulting value of null. Or even
with an actual value returned, the generic type could not be properly
determined. This change fixes both of those issues.

Issue: SPR-12287
This commit is contained in:
Rossen Stoyanchev
2014-10-15 16:39:03 -04:00
parent 6f987a9cf8
commit 956b66bbd4
3 changed files with 111 additions and 33 deletions

View File

@@ -17,6 +17,7 @@
package org.springframework.web.servlet.mvc.method.annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
@@ -45,6 +46,8 @@ import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.view.RedirectView;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* Test fixture with {@link ServletInvocableHandlerMethod}.
@@ -183,6 +186,37 @@ public class ServletInvocableHandlerMethodTests {
assertEquals("bar", response.getContentAsString());
}
// SPR-12287
@Test
public void wrapConcurrentResult_ResponseEntityNullBody() throws Exception {
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
converters.add(new StringHttpMessageConverter());
List<Object> advice = Arrays.asList(mock(ResponseBodyAdvice.class));
HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor(converters, null, advice);
returnValueHandlers.addHandler(processor);
ServletInvocableHandlerMethod handlerMethod = getHandlerMethod(new ResponseEntityHandler(), "handle");
handlerMethod = handlerMethod.wrapConcurrentResult(new ResponseEntity<>(HttpStatus.OK));
handlerMethod.invokeAndHandle(webRequest, mavContainer);
assertEquals(200, response.getStatus());
assertEquals("", response.getContentAsString());
}
@Test
public void wrapConcurrentResult_ResponseEntityNullReturnValue() throws Exception {
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
converters.add(new StringHttpMessageConverter());
List<Object> advice = Arrays.asList(mock(ResponseBodyAdvice.class));
HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor(converters, null, advice);
returnValueHandlers.addHandler(processor);
ServletInvocableHandlerMethod handlerMethod = getHandlerMethod(new ResponseEntityHandler(), "handle");
handlerMethod = handlerMethod.wrapConcurrentResult(null);
handlerMethod.invokeAndHandle(webRequest, mavContainer);
assertEquals(200, response.getStatus());
assertEquals("", response.getContentAsString());
}
private ServletInvocableHandlerMethod getHandlerMethod(Object controller,
String methodName, Class<?>... argTypes) throws NoSuchMethodException {