11/*
2- * Copyright 2002-2015 the original author or authors.
2+ * Copyright 2002-2016 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
5656 *
5757 * @author Rossen Stoyanchev
5858 * @author Sam Brannen
59+ * @author Juergen Hoeller
5960 */
6061public class ServletInvocableHandlerMethodTests {
6162
@@ -117,19 +118,17 @@ public void invokeAndHandle_VoidRequestNotModified() throws Exception {
117118 this .mavContainer .isRequestHandled ());
118119 }
119120
120- // SPR-9159
121-
122- @ Test
121+ @ Test // SPR-9159
123122 public void invokeAndHandle_NotVoidWithResponseStatusAndReason () throws Exception {
124123 ServletInvocableHandlerMethod handlerMethod = getHandlerMethod (new Handler (), "responseStatusWithReason" );
125124 handlerMethod .invokeAndHandle (this .webRequest , this .mavContainer );
126125
127- assertTrue ("When a status reason w/ used, the the request is handled" , this .mavContainer .isRequestHandled ());
126+ assertTrue ("When a status reason w/ used, the request is handled" , this .mavContainer .isRequestHandled ());
128127 assertEquals (HttpStatus .BAD_REQUEST .value (), this .response .getStatus ());
129128 assertEquals ("400 Bad Request" , this .response .getErrorMessage ());
130129 }
131130
132- @ Test (expected = HttpMessageNotWritableException .class )
131+ @ Test (expected = HttpMessageNotWritableException .class )
133132 public void invokeAndHandle_Exception () throws Exception {
134133 this .returnValueHandlers .addHandler (new ExceptionRaisingReturnValueHandler ());
135134
@@ -160,28 +159,52 @@ public void invokeAndHandle_DynamicReturnValue() throws Exception {
160159
161160 @ Test
162161 public void wrapConcurrentResult_MethodLevelResponseBody () throws Exception {
163- wrapConcurrentResult_ResponseBody (new MethodLevelResponseBodyHandler ());
162+ wrapConcurrentResult_ResponseBody (new MethodLevelResponseBodyHandler (), "bar" , String .class );
163+ }
164+
165+ @ Test
166+ public void wrapConcurrentResult_MethodLevelResponseBodyEmpty () throws Exception {
167+ wrapConcurrentResult_ResponseBody (new MethodLevelResponseBodyHandler (), null , String .class );
164168 }
165169
166170 @ Test
167171 public void wrapConcurrentResult_TypeLevelResponseBody () throws Exception {
168- wrapConcurrentResult_ResponseBody (new TypeLevelResponseBodyHandler ());
172+ wrapConcurrentResult_ResponseBody (new TypeLevelResponseBodyHandler (), "bar" , String .class );
173+ }
174+
175+ @ Test
176+ public void wrapConcurrentResult_TypeLevelResponseBodyEmpty () throws Exception {
177+ wrapConcurrentResult_ResponseBody (new TypeLevelResponseBodyHandler (), null , String .class );
178+ }
179+
180+ @ Test
181+ public void wrapConcurrentResult_DeferredResultSubclass () throws Exception {
182+ wrapConcurrentResult_ResponseBody (new DeferredResultSubclassHandler (), "bar" , String .class );
169183 }
170184
171- private void wrapConcurrentResult_ResponseBody (Object handler ) throws Exception {
172- List <HttpMessageConverter <?>> converters = new ArrayList <HttpMessageConverter <?>>();
185+ @ Test
186+ public void wrapConcurrentResult_DeferredResultSubclassEmpty () throws Exception {
187+ wrapConcurrentResult_ResponseBody (new DeferredResultSubclassHandler (), null , CustomDeferredResult .class );
188+ }
189+
190+ private void wrapConcurrentResult_ResponseBody (Object handler , Object result , Class <?> expectedReturnType )
191+ throws Exception {
192+
193+ List <HttpMessageConverter <?>> converters = new ArrayList <>();
173194 converters .add (new StringHttpMessageConverter ());
195+ this .returnValueHandlers .addHandler (new ModelAndViewMethodReturnValueHandler ());
174196 this .returnValueHandlers .addHandler (new RequestResponseBodyMethodProcessor (converters ));
175197 ServletInvocableHandlerMethod handlerMethod = getHandlerMethod (handler , "handle" );
176- handlerMethod = handlerMethod .wrapConcurrentResult ("bar" );
177- handlerMethod .invokeAndHandle (this .webRequest , this .mavContainer );
178198
179- assertEquals ("bar" , this .response .getContentAsString ());
199+ handlerMethod = handlerMethod .wrapConcurrentResult (result );
200+ handlerMethod .invokeAndHandle (this .webRequest , this .mavContainer );
201+ assertEquals ((result != null ? result .toString () : "" ), this .response .getContentAsString ());
202+ assertEquals (expectedReturnType , handlerMethod .getReturnValueType (result ).getParameterType ());
180203 }
181204
182205 @ Test
183206 public void wrapConcurrentResult_ResponseEntity () throws Exception {
184- List <HttpMessageConverter <?>> converters = new ArrayList <HttpMessageConverter <?> >();
207+ List <HttpMessageConverter <?>> converters = new ArrayList <>();
185208 converters .add (new StringHttpMessageConverter ());
186209 this .returnValueHandlers .addHandler (new HttpEntityMethodProcessor (converters ));
187210 ServletInvocableHandlerMethod handlerMethod = getHandlerMethod (new ResponseEntityHandler (), "handleDeferred" );
@@ -191,11 +214,9 @@ public void wrapConcurrentResult_ResponseEntity() throws Exception {
191214 assertEquals ("bar" , this .response .getContentAsString ());
192215 }
193216
194- // SPR-12287
195-
196- @ Test
217+ @ Test // SPR-12287
197218 public void wrapConcurrentResult_ResponseEntityNullBody () throws Exception {
198- List <HttpMessageConverter <?>> converters = new ArrayList <HttpMessageConverter <?> >();
219+ List <HttpMessageConverter <?>> converters = new ArrayList <>();
199220 converters .add (new StringHttpMessageConverter ());
200221 List <Object > advice = Collections .singletonList (mock (ResponseBodyAdvice .class ));
201222 HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor (converters , null , advice );
@@ -210,7 +231,7 @@ public void wrapConcurrentResult_ResponseEntityNullBody() throws Exception {
210231
211232 @ Test
212233 public void wrapConcurrentResult_ResponseEntityNullReturnValue () throws Exception {
213- List <HttpMessageConverter <?>> converters = new ArrayList <HttpMessageConverter <?> >();
234+ List <HttpMessageConverter <?>> converters = new ArrayList <>();
214235 converters .add (new StringHttpMessageConverter ());
215236 List <Object > advice = Collections .singletonList (mock (ResponseBodyAdvice .class ));
216237 HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor (converters , null , advice );
@@ -225,7 +246,7 @@ public void wrapConcurrentResult_ResponseEntityNullReturnValue() throws Exceptio
225246
226247 @ Test
227248 public void wrapConcurrentResult_ResponseBodyEmitter () throws Exception {
228- List <HttpMessageConverter <?>> converters = new ArrayList <HttpMessageConverter <?> >();
249+ List <HttpMessageConverter <?>> converters = new ArrayList <>();
229250 converters .add (new StringHttpMessageConverter ());
230251 this .returnValueHandlers .addHandler (new ResponseBodyEmitterReturnValueHandler (converters ));
231252 ServletInvocableHandlerMethod handlerMethod = getHandlerMethod (new AsyncHandler (), "handleWithEmitter" );
@@ -247,9 +268,7 @@ public void wrapConcurrentResult_StreamingResponseBody() throws Exception {
247268 assertEquals ("" , this .response .getContentAsString ());
248269 }
249270
250- // SPR-12287 (16/Oct/14 comments)
251-
252- @ Test
271+ @ Test // SPR-12287 (16/Oct/14 comments)
253272 public void responseEntityRawTypeWithNullBody () throws Exception {
254273 List <HttpMessageConverter <?>> converters = Collections .singletonList (new StringHttpMessageConverter ());
255274 List <Object > advice = Collections .singletonList (mock (ResponseBodyAdvice .class ));
@@ -272,6 +291,8 @@ private ServletInvocableHandlerMethod getHandlerMethod(Object controller,
272291 return handlerMethod ;
273292 }
274293
294+
295+ @ SuppressWarnings ("unused" )
275296 @ ResponseStatus
276297 @ Retention (RetentionPolicy .RUNTIME )
277298 @interface ComposedResponseStatus {
@@ -280,6 +301,7 @@ private ServletInvocableHandlerMethod getHandlerMethod(Object controller,
280301 HttpStatus responseStatus () default HttpStatus .INTERNAL_SERVER_ERROR ;
281302 }
282303
304+
283305 @ SuppressWarnings ("unused" )
284306 private static class Handler {
285307
@@ -311,6 +333,16 @@ public Object dynamicReturnValue(@RequestParam(required=false) String param) {
311333 }
312334 }
313335
336+
337+ @ SuppressWarnings ("unused" )
338+ @ ResponseStatus (HttpStatus .BAD_REQUEST )
339+ private static class ResponseStatusHandler {
340+
341+ public void handle () {
342+ }
343+ }
344+
345+
314346 private static class MethodLevelResponseBodyHandler {
315347
316348 @ ResponseBody
@@ -319,15 +351,30 @@ public DeferredResult<String> handle() {
319351 }
320352 }
321353
354+
322355 @ SuppressWarnings ("unused" )
323356 @ ResponseBody
324357 private static class TypeLevelResponseBodyHandler {
325358
326359 public DeferredResult <String > handle () {
327- return new DeferredResult <String >();
360+ return new DeferredResult <>();
328361 }
329362 }
330363
364+
365+ private static class DeferredResultSubclassHandler {
366+
367+ @ ResponseBody
368+ public CustomDeferredResult handle () {
369+ return new CustomDeferredResult ();
370+ }
371+ }
372+
373+
374+ private static class CustomDeferredResult extends DeferredResult <String > {
375+ }
376+
377+
331378 @ SuppressWarnings ("unused" )
332379 private static class ResponseEntityHandler {
333380
@@ -340,6 +387,7 @@ public ResponseEntity<Void> handleRawType() {
340387 }
341388 }
342389
390+
343391 private static class ExceptionRaisingReturnValueHandler implements HandlerMethodReturnValueHandler {
344392
345393 @ Override
@@ -354,6 +402,7 @@ public void handleReturnValue(Object returnValue, MethodParameter returnType,
354402 }
355403 }
356404
405+
357406 @ SuppressWarnings ("unused" )
358407 private static class AsyncHandler {
359408
@@ -366,4 +415,4 @@ public StreamingResponseBody handleWithStreaming() {
366415 }
367416 }
368417
369- }
418+ }
0 commit comments