请求方法参数的处理HandlerMethodArgumentResolver和响应返回值的处理HandlerMethodReturnValueHandler
SpringMVC处理请求大致是这样的:
首先被DispatcherServlet截获,DispatcherServlet通过handlerMapping获得HandlerExecutionChain,然后获得HandlerAdapter。
HandlerAdapter在内部对于每个请求,都会实例化一个ServletInvocableHandlerMethod进行处理,ServletInvocableHandlerMethod在进行处理的时候,会分两部分别对请求跟响应进行处理。
之后HandlerAdapter得到ModelAndView,然后做相应的处理。
ServletInvocableHandlerMethod#invokeAndHandle对请求以及响应的处理。
public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer, Object… providedArgs_) _throws Exception { //具体处理请求逻辑Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs); setResponseStatus(webRequest); if (returnValue == null) { __ _if (_isRequestNotModified(webRequest) || getResponseStatus() != null || mavContainer.isRequestHandled()) { __ mavContainer.setRequestHandled(_true)_; return; } } _else if (_StringUtils.hasText(getResponseStatusReason())) { __ mavContainer.setRequestHandled(_true)_; return; } mavContainer.setRequestHandled(_false)_; Assert.state_(_this.returnValueHandlers != null, “No return value handlers”); try { __ //返回值处理逻辑 this.returnValueHandlers.handleReturnValue( __ returnValue, getReturnValueType(returnValue), mavContainer, webRequest); } __ _catch (_Exception ex) { __ _if (_logger.isTraceEnabled()) { _ _logger.trace(formatErrorForReturnValue(returnValue), ex); } _ _throw ex; } __} |
---|
处理请求的时候,会根据ServletInvocableHandlerMethod的属性argumentResolvers(这个属性是它的父类InvocableHandlerMethod中定义的)进行处理,其中argumentResolvers属性是一个HandlerMethodArgumentResolverComposite类(这里使用了组合模式的一种变形),这个类是实现了HandlerMethodArgumentResolver接口的类,里面有各种实现了HandlerMethodArgumentResolver的List集合。
处理响应的时候,会根据ServletInvocableHandlerMethod的属性returnValueHandlers(自身属性)进行处理,returnValueHandlers属性是一个HandlerMethodReturnValueHandlerComposite类(这里使用了组合模式的一种变形),这个类是实现了HandlerMethodReturnValueHandler接口的类,里面有各种实现了HandlerMethodReturnValueHandler的List集合。
被加入到Spring容器的时机
RequestMappingHandlerAdapter的argumentResolvers和returnValueHandlers这两个属性是在 RequestMappingHandlerAdapter#afterPropertiesSet进行实例化的时候被Spring容器注入的。
@Override public void afterPropertiesSet() { __ // Do this first, it may add ResponseBody advice beans //支持@ControllerAdvice注解 initControllerAdviceCache(); if _(_this.argumentResolvers == null) { __ //初始化ArgumentResolvers List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers(); this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers); } __ _if (_this.initBinderArgumentResolvers == null) { __ List<HandlerMethodArgumentResolver> resolvers = getDefaultInitBinderArgumentResolvers(); this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers); } __ _if (_this.returnValueHandlers == null) { __ //初始化ReturnValueHandlers List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers(); this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers); } __} |
---|
RequestMappingHandlerAdapter#getDefaultArgumentResolvers对ArgumentResolvers进行初始化
RequestMappingHandlerAdapter#getDefaultReturnValueHandlers对ReturnValueHandlers进行初始化
参数解析实现类
1. RequestParamMethodArgumentResolver
支持带有@RequestParam注解的参数或带有MultipartFile类型的参数
2. RequestParamMapMethodArgumentResolver
支持带有@RequestParam注解的参数 && @RequestParam注解的属性value存在 && 参数类型是实现Map接口的属性
3. PathVariableMethodArgumentResolver
支持带有@PathVariable注解的参数 且如果参数实现了Map接口,@PathVariable注解需带有value属性
4. MatrixVariableMethodArgumentResolver
支持带有@MatrixVariable注解的参数 且如果参数实现了Map接口,@MatrixVariable注解需带有value属性
5. RequestResponseBodyMethodProcessor
本文已分析过
6. ServletRequestMethodArgumentResolver
参数类型是实现或继承或是WebRequest、ServletRequest、MultipartRequest、HttpSession、Principal、Locale、TimeZone、InputStream、Reader、HttpMethod这些类。
(这就是为何我们在Controller中的方法里添加一个HttpServletRequest参数,Spring会为我们自动获得HttpServletRequest对象的原因)
7. ServletResponseMethodArgumentResolver
参数类型是实现或继承或是ServletResponse、OutputStream、Writer这些类
8. RedirectAttributesMethodArgumentResolver
参数是实现了RedirectAttributes接口的类
9. HttpEntityMethodProcessor
参数类型是HttpEntity
返回值解析实现类
- ModelAndViewMethodReturnValueHandler
返回值类型是ModelAndView或其子类
2. ModelMethodProcessor
返回值类型是Model或其子类
3. ViewMethodReturnValueHandler
返回值类型是View或其子类
4. HttpHeadersReturnValueHandler
返回值类型是HttpHeaders或其子类
5. ModelAttributeMethodProcessor
返回值有@ModelAttribute注解
6. ViewNameMethodReturnValueHandler
返回值是void或String
@RequestBody解析
@ResponseBody注解的话最终返回值会被RequestResponseBodyMethodProcessor这个HandlerMethodReturnValueHandler实现类处理.RequestResponseBodyMethodProcessor这个类其实同时实现了HandlerMethodReturnValueHandler和HandlerMethodArgumentResolver这两个接口。