说明
- Handler——http请求具体的处理类,简单理解为Controller中的@RequestMapping注解方法
- HandlerMapping——把reuqest请求映射到Handler
- HandleAdapter——怎么把Servlet请求转换Handler的需要参数形式,并使用Handler来处理request请求
1. HandlerMapping介绍
HandlerMapping就是根据Request找到对应的处理Handler和Interceptors。HandlerMapping 的方法只有一个,根据request获取HandlerExecutionChain
HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
HandlerExecutionChain里面包含了若干Interceptor和一个具体的Handler。
在DispatcherServlet中,有个方法
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { for (HandlerMapping hm : this.handlerMappings) { if (logger.isTraceEnabled()) { logger.trace( "Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'"); } HandlerExecutionChain handler = hm.getHandler(request); if (handler != null) { return handler; } } return null; }
就是通过request,在HandlerMapping列表中查找,找到第一个就返回HandlerExecutionChain
2. HandlerAdapter
从下面注释可以看出,HandlerAdapter的作用就是用request来调用handler的处理类(因为每个controller的方法的参数都是不一样的)
public interface HandlerAdapter { /** * 判断当前adapter是否支持该handler示例 */ boolean supports(Object handler); /** * 使用参数中的handler处理参数中的request */ ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception; long getLastModified(HttpServletRequest request, Object handler); }
在DispatcherServlet中的getHandlerAdpater方法中,也是遍历所有的handlerAdpater,找出第一个能support的去处理。
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException { for (HandlerAdapter ha : this.handlerAdapters) { if (logger.isTraceEnabled()) { logger.trace("Testing handler adapter [" + ha + "]"); } if (ha.supports(handler)) { return ha; } } throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler"); }
3. HandlerExceptionResolver
当在上面的处理过程中出现Exception 的时候,就需要一个专门处理异常的类(就算出问题了,总也得给点反馈吧)。而HandlerExceptionResolver就是来做这种事情的。我们做统一错误页或者记录错误日志的时候就可以实现该接口
public interface HandlerExceptionResolver { /** * 出现异常的时候会调用改方法 */ ModelAndView resolveException( HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex); }
4. ViewResolver
这个组件的作用就是渲染页面,在Dispatcher中的应用如下:
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception { Locale locale = this.localeResolver.resolveLocale(request); response.setLocale(locale); View view; if (mv.isReference()) { // We need to resolve the view name. view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request); if (view == null) { throw new ServletException("Could not resolve view with name '" + mv.getViewName() + "' in servlet with name '" + getServletName() + "'"); } } else { // No need to lookup: the ModelAndView object contains the actual View object. view = mv.getView(); if (view == null) { throw new ServletException("ModelAndView [" + mv + "] neither contains a view name nor a " + "View object in servlet with name '" + getServletName() + "'"); } } // Delegate to the View object for rendering. if (logger.isDebugEnabled()) { logger.debug("Rendering view [" + view + "] in DispatcherServlet with name '" + getServletName() + "'"); } try { if (mv.getStatus() != null) { response.setStatus(mv.getStatus().value()); } view.render(mv.getModelInternal(), request, response); } catch (Exception ex) { if (logger.isDebugEnabled()) { logger.debug("Error rendering view [" + view + "] in DispatcherServlet with name '" + getServletName() + "'", ex); } throw ex; } }
首先是先找出渲染视图locale(地区,例如zn),然后根据locale调用ViewResolver的解析方法生成View。最后用view渲染。
ViewResolver的作用就是根据视图名(viewName)找出对应的视图(可以理解为一个地址),而视图的作用就是填充模板中的一些参数(JSTL或是Freemaker)。接口如下:
public interface ViewResolver { View resolveViewName(String viewName, Locale locale) throws Exception; }
5. RequestToViewNameTranslator
前面介绍ViewResolver的作用是根据viewName来查找出对应的视图,但是有些handler处理过程中并没有设置视图,而RequestToViewNameTranslator就是根据request找出视图。
6. MultipartResolver
用于处理上传请求。将普通的requet封装为MultipartHttpServletRequest。后者直接可以获取文件。
7. FlashMapManager
这个主要是再出redirect的时候传递参数。
public interface FlashMapManager { /** * 恢复和更新参数 */ FlashMap retrieveAndUpdate(HttpServletRequest request, HttpServletResponse response); /** * 将参数保存到FlashMap中 */ void saveOutputFlashMap(FlashMap flashMap, HttpServletRequest request, HttpServletResponse response); }