JavaWeb學習之——Spring篇之Spring MVC組件簡介

說明

  1.  Handler——http請求具體的處理類,簡單理解爲Controller中的@RequestMapping註解方法
  2.  HandlerMapping——把reuqest請求映射到Handler
  3.  HandleAdapter——怎麼把Servlet請求轉換Handler的須要參數形式,並使用Handler來處理request請求

1. HandlerMapping介紹

HandlerMapping就是根據Request找到對應的處理Handler和Interceptors。HandlerMapping 的方法只有一個,根據request獲取HandlerExecutionChainapp

HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;

HandlerExecutionChain裏面包含了若干Interceptor和一個具體的Handler。this

在DispatcherServlet中,有個方法spa

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列表中查找,找到第一個就返回HandlerExecutionChaindebug

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就是來作這種事情的。咱們作統一錯誤頁或者記錄錯誤日誌的時候就能夠實現該接口ip

public interface HandlerExceptionResolver {

   /**
    * 出現異常的時候會調用改方法
    */
   ModelAndView resolveException(
         HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex);
}

4. ViewResolver

這個組件的做用就是渲染頁面,在Dispatcher中的應用以下:get

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渲染。servlet

ViewResolver的做用就是根據視圖名(viewName)找出對應的視圖(能夠理解爲一個地址),而視圖的做用就是填充模板中的一些參數(JSTL或是Freemaker)。接口以下:flash

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);

}
相關文章
相關標籤/搜索