HandlerMethodReturnValueHandler是RequestMappingHandlerAdapter用来处理当含有@RequestMapping的方法调度完成后,后面要进行的事情。  
 首先是HandlerMethodReturnValueHandler的自定义注册:  
 mvc:annotation-driven配置如下:  
1. <mvc:annotation-driven>  
2. return-value-handlers>  
3. class="org.springframework.web.servlet.mvc.method.annotation.ModelAndViewMethodReturnValueHandler"></bean>  
4. return-value-handlers>  
5.     </mvc:annotation-driven> 
在启动AnnotationDrivenBeanDefinitionParser来解析mvc:annotation-driven标签的过程中(见本系列第三篇博客),会注册我们所配置的HandlerMethodReturnValueHandler,如下:
1. ManagedList<?> returnValueHandlers = getReturnValueHandlers(element, parserContext);1. private
2. "return-value-handlers");  
3. if (handlersElement != null) {  
4. return
5.         }  
6. return null;  
7.     } 
然后将会这些自定义的HandlerMethodReturnValueHandler设置到RequestMappingHandlerAdapter的customReturnValueHandlers属性中, 
 RequestMappingHandlerAdapter的两个重要属性: 
 customReturnValueHandlers:存放我们自定义的HandlerMethodReturnValueHandler; 
 returnValueHandlers:存放最终所有的HandlerMethodReturnValueHandler; 
如下所示:
1. public class RequestMappingHandlerAdapter extends
2. implements
3.   
4. private
5.   
6. private
7.   
8. private
9.   
10. //这里这里这里这里这里这里这里这里
11. private
12. //这里这里这里这里这里这里这里这里
13. private 
returnValueHandlers的属性类型为HandlerMethodReturnValueHandlerComposite,里面也有一个list集合,来存放所有的HandlerMethodReturnValueHandler。 
HandlerMethodReturnValueHandlerComposite结构如下:
1. public class HandlerMethodReturnValueHandlerComposite implements
2.   
3. protected final
4.   
5. private final
6. new
7.   
8.     /** 
在RequestMappingHandlerAdapter创建出来后,会执行afterPropertiesSet()方法,在该方法中会设置所有的HandlerMethodReturnValueHandler到RequestMappingHandlerAdapter的returnValueHandlers属性中如下:  
1. @Override
2. public void
3. if (this.argumentResolvers == null) {  
4.             List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers();  
5. this.argumentResolvers = new
6.         }  
7. if (this.initBinderArgumentResolvers == null) {  
8.             List<HandlerMethodArgumentResolver> resolvers = getDefaultInitBinderArgumentResolvers();  
9. this.initBinderArgumentResolvers = new
10.         }  
11. if (this.returnValueHandlers == null) {  
12. //获取所有的HandlerMethodReturnValueHandler
13.             List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers();  
14. this.returnValueHandlers = new
15.         }  
16.         initControllerAdviceCache();  
17.     }  
 
   
getDefaultReturnValueHandlers()方法会获取默认要注册的和我们自定义的HandlerMethodReturnValueHandler,如下:  
1. private
2. new
3.   
4. // Single-purpose return value types
5. new
6. new
7. new
8. new HttpEntityMethodProcessor(getMessageConverters(), this.contentNegotiationManager));  
9. new
10. new
11. new
12. new AsyncTaskMethodReturnValueHandler(this.beanFactory));  
13.   
14. // Annotation-based return value types
15. new ModelAttributeMethodProcessor(false));  
16. new RequestResponseBodyMethodProcessor(getMessageConverters(), this.contentNegotiationManager));  
17.   
18. // Multi-purpose return value types
19. new
20. new
21.   
22. // Custom return value types
23. //这里这里会从customReturnValueHandlers属性中获取我们自定的HandlerMethodReturnValueHandler
24. if (getCustomReturnValueHandlers() != null) {  
25.             handlers.addAll(getCustomReturnValueHandlers());  
26.         }  
27.   
28. // Catch-all
29. if
30. new
31.         }  
32. else
33. new ModelAttributeMethodProcessor(true));  
34.         }  
35.   
36. return
37.     } 
至此,所有的HandlerMethodReturnValueHandler的注册已经完成。我们可以再回顾下,在该系列的第三篇博客中介绍HandlerMethodReturnValueHandler的使用。 
 第一步:获取合适的HandlerAdapter,当方法含有@RequestMaiing注释的时候,便选择RequestMappingHandlerAdapter来进行方法的调度处理 
 第二步:方法的调度处理过程为:首先执行方法体,然后根据返回值来选择一个合适的HandlerMethodReturnValueHandler,如下代码:  
1. public final void
2. throws
3.   
4.         Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);  
5.   
6.         setResponseStatus(webRequest);  
7.   
8. if (returnValue == null) {  
9. if
10. true);  
11. return;  
12.             }  
13.         }  
14. else if (StringUtils.hasText(this.responseReason)) {  
15. true);  
16. return;  
17.         }  
18.   
19. false);  
20. //重点重点重点重点重点重点重点重点重点重点
21. try
22. this.returnValueHandlers.handleReturnValue(returnValue, getReturnValueType(returnValue), mavContainer, webRequest);  
23.         }  
24. catch
25. if
26. "Error handling return value", returnValue), ex);  
27.             }  
28. throw
29.         }  
30.     }  
 
   
this.returnValueHandlers.handleReturnValue(returnValue, getReturnValueType(returnValue), mavContainer, webRequest)会遍历所有的已注册的HandlerMethodReturnValueHandler判断他们支不支持returnValue的返回类型。如下:  
1. public void
2.             Object returnValue, MethodParameter returnType,  
3.             ModelAndViewContainer mavContainer, NativeWebRequest webRequest)  
4. throws
5.   
6.         HandlerMethodReturnValueHandler handler = getReturnValueHandler(returnType);  
7. "Unknown return value type [" + returnType.getParameterType().getName() + "]");  
8.         handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);  
9.     }  
10.   
11. /**
12.      * Find a registered {@link HandlerMethodReturnValueHandler} that supports the given return type.
13.      */
14. private
15. for
16. if
17. "Testing if return value handler [" + returnValueHandler + "] supports ["
18. "]");  
19.             }  
20. if
21. return
22.             }  
23.         }  
24. return null;  
25.     }  
 
  找到支持的HandlerMethodReturnValueHandler后,就要执行它的handleReturnValue方法。 
 下面就具体介绍下下常用的这几个HandlerMethodReturnValueHandler; 
 HttpEntityMethodProcessor:用来处理返回值类型是HttpEntity的方法,简单用法如下  
1. @RequestMapping(value="/test/httpEntity",method=RequestMethod.GET)  
2. public HttpEntity<String> testHttpEntity() throws
3. "中国";  
4. new
5. "Content-type","text/html;charset=GBK");  
6. new
7. return
8.     } 
就是在构建http协议的返回体和返回头。 
 使用案例如,文件下载。 
 经常有人直接用HttpServletRequest和HttpServletResponse来做文件下载,这种方式便与web容器产生的对象耦合在一起,不推荐使用,而是直接使用spring为我们提供的HttpEntityMethodProcessor这一返回值处理器,虽然springmvc最终还是用HttpServletResponse来实现,但是这种方式便断开我们直接与web容器之间的耦合。 
 这一过程分析: 
 当这个方法执行完成之后,会调用HttpEntityMethodProcessor的handleReturnValue方法, 
 该方法内容就是为response设置响应头,然后将响应体的内容写入response的body中,此时又会涉及到HttpMessageConverter,当HttpEntity中的body类型为String,又会让StringHttpMessageConverter来进行转换。这和@ResponseBody的处理过程是一样的。 
 ViewNameMethodReturnValueHandler:主要用来处理返回值是String类型(前提不含@ResponseBody标签),它会将返回的字符串作为view视图的名字,如下所示。 

 另一种用法,当返回的字符串以redirect:开始,不再作为view视图名而是作为重定向的地址,如下:  
1. @RequestMapping(value="/test/string",method=RequestMethod.GET)  
2. public
3. return "redirect:/string";  
4.     }  
5.       
 
  
有了重定向,也有转发。以forward:开头便是转发。  
如下:
1. @RequestMapping(value="/test/string",method=RequestMethod.GET)  
2. public
3. return "forward:/string";  
4.     } 
ModelMethodProcessor:用来处理返回类型为Model的,它默认采用请求路径作为视图名称,如下:
1. @RequestMapping(value="/test/model",method=RequestMethod.GET)  
2. public Model handleModel(String name) throws
3. new
4. "name",name);  
5. return
6.     } 

ModelAndViewMethodReturnValueHandler:用来处理返回值类型为ModelAndView,如下:  
1. @RequestMapping(value="/test/modelandview",method=RequestMethod.GET)  
2. public ModelAndView testModelAndView() throws
3. return new ModelAndView("hello");  
4.     }  
 
   
 RequestResponseBodyMethodProcessor:则是用于处理方法中含有@ResponseBody注解,或类上含有@ResponseBody注解。这一处理过程在本系列的第三篇博客中有介绍,这里不再叙述。 
 还有其他的HandlerMethodReturnValueHandler,这里仅仅是作为引路,对HandlerMethodReturnValueHandler有个整体的认识,具体的内容,需要读者去具体研究。
 
 
                     
            
        













 
                    

 
                 
                    