1. 程式人生 > 實用技巧 >springMVC學習(二)工作流程

springMVC學習(二)工作流程

springMVC工作流程

  • 使用者傳送請求,請求交由SpringMVC核心控制器處理

  • 核心控制器找到對映器看該請求是否交由對應的Action類進行處理

  • 核心控制器再找到介面卡看有無該Action類

  • Action類處理完業務之後返回一個ModelAndView物件

  • 最後通過檢視解析器來對ModelAndView進行解析,跳轉到對應的JSP/html頁面

核心控制器

在web.xml中配置DispatcherServlet

SpringMVC配置檔案的預設路徑是WEB-INF下面,且配置檔案的name預設應該是你配置的DispatcherServlet的servlet-name+servlet.xml(即DispatcherServlet-servlet.xml)

  • 如果配置檔案放在WEB-INF目錄下,但是name不是預設格式,可以通過namespace這個初始化引數進行指定

  <init-param>
<!-- 如果springmvc的配置檔案springmvc.xml放在WEB-INF目錄下,
但名字的形式不是*-servlet.xml,則可以通過namespace屬性值進行指定 -->
<param-name>namespace</param-name>
<param-value>springmvc</param-value>
</init-param>
  • 如果配置檔案不在WEB-INF目錄下,則通過contextConfigLocation這個初始化引數進行指定位置和檔名

  <!--到類目錄下尋找我們的配置檔案applicationContext.xml-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
  • SpringMVC過濾編碼器

    在web.xml配置檔案中設定過濾編碼器,該過濾編碼器只能解決POST的亂碼問題

 <!--編碼過濾器-->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<!--過濾所有請求-->
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
  • 防止jsp中的靜態中文亂碼,在jsp首行設定編碼格式 utf-8

<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="utf-8" %>

對映器 HandlerMapping

handlerMapping獲取到執行請求的Controller類和執行方法

  • 在web.xml中配置規定只要是.action為字尾的請求都是會經過SpringMVC的核心Servlet

  • 當我們接收到請求的時候,我們發現是hello.action,是會經過我們的核心Servlet的,那麼核心Servlet就會去找有沒有專門的Action類來處理hello.action請求的

  • 在applicationContext.xml中name屬性就是規定了hello.action到HelloAction控制器中處理

對映器預設的值是這樣的:

 <!-- 註冊對映器(handler包)(框架)【可省略】 -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
</bean>

在建立控制器的時候可以不使用name屬性來指定路徑,可以使用對映器來配置。如以下的程式碼

  <bean class="HelloAction" id="helloAction"></bean>

<!-- 註冊對映器(handler包)(框架) -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/hello.action">helloAction</prop>
<!--當我們需要多個請求路徑都交由helloAction控制器來處理的話,我們只要新增prop標籤就行了!--> <prop key="/bye.action">helloAction</prop>
</props>
</property>
</bean>

介面卡 HandlerAdapter

根據handlerMapping傳過來的controller與已經註冊好了的HandlerAdapter一一匹配,看哪一種HandlerAdapter是支援該controller型別的

當我們對映器找到對應的Action來處理請求的時候,核心控制器會讓介面卡去找該類是否實現了Controller介面【預設可省略的】

  <!-- 介面卡【可省略】 -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>

檢視解析器

我們把結果封裝到ModelAndView以後,SpringMVC會使用檢視解析器來對ModelAndView進行解析。【真實路徑時,預設可省略的】

如果我們用的是邏輯路徑(只有檔名,沒有後綴),那麼就必須對其配置,否則SpringMVC是找不到對應的路徑的,如果用邏輯路徑,就需要在applicationContext.xml中新增檢視解析器

  • 如果Action中寫的是檢視邏輯名稱,那麼檢視解析器就必須配置

  • 如果Action中寫的是檢視真實名稱,那麼檢視解析器就可選配置

  <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 路徑字首 -->
<property name="prefix" value="/"/>
<!-- 路徑字尾 -->
<property name="suffix" value=".jsp"/>
<!-- 字首+檢視邏輯名+字尾=真實路徑 -->
</bean>

控制器

Handler,是對Controller的Bean本身和請求Method的包裝。而HandlerExecutionChain 是handler的二次包裝,將handler與攔截器鏈關聯到了一起。然後,在DispatcherServlert中完成了攔截器鏈對handler的過濾。

對映器和介面卡

  • 對映器

    • SpringMVC預設提供了兩種HandlerMapping:BeanNameUrlHandlerMapping、DefaultAnnotationHandlerMapping

    • HandlerMapping的任務就是建立url與Bean(Controller)的對應關係,並將對應關係儲存在handlerMap中

  • 介面卡

    • DispatcherServlte會根據配置檔案資訊註冊HandlerAdapter,如果在配置檔案中沒有配置,那麼DispatcherServlte會獲取HandlerAdapter的預設配置,如果是讀取預設配置的話,DispatcherServlte會讀取DispatcherServlte.properties檔案,該檔案中配置了三種HandlerAdapter:HttpRequestHandlerAdapter,SimpleControllerHandlerAdapter和AnnotationMethodHandlerAdapter。DispatcherServlte會將這三個HandlerAdapter物件儲存到它的handlerAdapters這個集合屬性中,這樣就完成了HandlerAdapter的註冊。

    • DispatcherServlte會根據handlerMapping傳過來的controller與已經註冊好了的HandlerAdapter一一匹配,看哪一種HandlerAdapter是支援該controller型別的,如果找到了其中一種HandlerAdapter是支援傳過來的controller型別,那麼該HandlerAdapter會呼叫自己的handle方法,handle方法運用Java的反射機制執行controller的具體方法來獲得ModelAndView,例如SimpleControllerHandlerAdapter是支援實現了controller介面的控制器,如果自己寫的控制器實現了controller介面,那麼SimpleControllerHandlerAdapter就會去執行自己寫控制器中的具體方法來完成請求

  • 對映器和介面卡的對應關係

    • AnnotationMethodHandlerAdapter主要是適配註解類處理器,註解類處理器就是我們經常使用的@Controller的這類處理器

    • HttpRequestHandlerAdapter主要是適配靜態資源處理器,靜態資源處理器就是實現了HttpRequestHandler介面的處理器,這類處理器的作用是處理通過SpringMVC來訪問的靜態資源的請求。

    • SimpleControllerHandlerAdapter是Controller處理介面卡,適配實現了Controller介面或Controller介面子類的處理器,比如我們經常自己寫的Controller來繼承MultiActionController,那麼自己寫的這些Controller就會由SimpleControllerHandlerAdapter來適

    • SimpleServletHandlerAdapter是Servlet處理介面卡,適配實現了Servlet介面或Servlet的子類的處理器,我們不僅可以在web.xml裡面配置Servlet,其實也可以用SpringMVC來配置Servlet,不過這個介面卡很少用到,而且SpringMVC預設的介面卡沒有他,預設的是前面的三種。