HTTP请求到达Controller层时,需要将请求中的参数转换成java可识别的参数,等Controller处理完成后,又需要将java的返回值转换为HTTP内容返回给用户。
先回顾SpringMVC调用Controller的入口位置,这里会调用HandlerAdapter,让HandlerAdapter调用实际的Controller方法。但这个方法可能包含不同的参数和返回值,就需要对参数和返回值进行绑定。
1 | protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { |
一、初始化
常用的一个URL对应一个方法使用的是RequestMappingHandlerAdapter,这也是要研究的重点。这个类在afterPropertiesSet()方法会初始化参数绑定工具HandlerMethodArgumentResolver和返回值绑定工具HandlerMethodReturnValueHandler
1 | @Override |
二、普通方法的参数绑定过程
一路跟着doDispatch方法的handle下去,在使用反射调用实际Handle方法之前,会对方法的每次参数进行绑定,待Handle处理完成之后,又会对返回值进行处理。
1 | @Override |
要使用哪个resolver来绑定参数呢?在RequestMappingHandlerAdapter初始化时已经默认定义了一系列resolver,如果任意一个能支持解析参数,就会使用它来解析参数。
常用的HandlerMethodArgumentResolver有这些:
RequestResponseBodyMethodProcessor:解析注释了@RequestBody类型的参数
PathVariableMethodArgumentResolver:解析注释了@PathVariable而且不是Map类型的参数
RequestHeaderMethodArgumentResolver:解析注释了@RequestHeader的Map类型的参数
RequestParamMethodArgumentResolver:解析注释了@RequestParam的参数
ModelMethodProcessor:解析Model类型的参数
三、RESTful方法的参数绑定过程
如果一个方法使用了@ResponseBody注解,将会使用RequestResponseBodyMethodProcessor来对参数和返回值进行处理。
以RequestResponseBodyMethodProcessor的参数绑定举例:从messageConverters中取出一个合适的来进行参数绑定,这和选择ArgumentResolver的套路如出一辙。
1 | @Override |
哦对了,这个messageConverter一般需要自己进行配置,一般这样配置:
1 | <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> |