DispatcherServlet詳解


DispatcherServlet

和其它web框架一樣,Spring的web框架是一個請求驅動的web框架,其設計圍繞一個中心的servlet進行,它能將請求分發給控制器,並提供其它功能幫助web應用開發。然而,Spring的DispatcherServlet所做的不僅僅是這些,它和Spring的IoC容器完全集成在一起,從而允許你使用Spring的其它功能。

下圖展示了DispatcherServlet對請求的處理流程。熟悉設計模式的讀者可能會發現DispatcherServlet應用了“Front Controller”這個模式(很多其他的主流web框架也都用到了這個模式)。

 

Spring Web MVC處理請求的工作流程

 

DispatcherServlet實際上是一個Servlet(它從HttpServlet繼承而來)。和其它Servlet一樣,DispatcherServlet定義在web應用的web.xml文件里。DispatcherServlet處理的請求必須在同一個web.xml文件里使用url-mapping定義映射。下面的例子演示了如何配置DispatcherServlet

<web-app>

    <servlet>
        <servlet-name>example</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>example</servlet-name>
        <url-pattern>*.form</url-pattern>
    </servlet-mapping>

</web-app>

在上面的例子里,所有以.form結尾的請求都會由名為exampleDispatcherServlet處理。這只是配置Spring Web MVC的第一步。接下來需要配置DispatcherServlet本身和Spring Web MVC 框架用到的其他的bean。

正如在第 3.8 節 “ApplicationContext中所描述的,Spring中的ApplicationContext可以被限制在不同的作用域(scope)中。在web MVC框架中,每個DispatcherServlet有它自己的WebApplicationContext,這個context繼承了根 WebApplicationContext的所有bean定義。這些繼承的bean也可以在每個serlvet自己的所屬的域中被覆蓋(override),覆蓋后的bean可以被設置成只有這個servlet實例自己才可以使用的屬性。

 

Spring Web MVC中的Context體系

 

DispatcherServlet的初始化過程中,Spring會在web應用的WEB-INF文件夾下尋找名為[servlet-name]-servlet.xml的配置文件,生成文件中定義的bean。這些bean會覆蓋在全局范圍(global cope)中定義的同名的bean。

下面這個例子展示了在web.xmlDispatcherServlet的配置:

<web-app>
    ...
    <servlet>
        <servlet-name>golfing</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>golfing</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app>

要進行如上的servlet配置,你還需要配置/WEB-INF/golfing-servlet.xml這樣一個文件。golfing-servlet.xml這個文件應該聲明你在Spring Web MVC 框架中需要的bean。 這個文件的路徑也可以通過web.xml中servlet的初始化參數來更改。(詳情見下面的例子。)

WebApplicationContext僅僅是一個擁有web應用必要功能的普通ApplicationContext。它與一個標准的ApplicationContext的不同之處在於,它能夠解析theme(參考第 13.7 節 “使用主題”),並且它知道自己與哪個servlet相關聯(通過ServletContext)。WebApplicationContext被綁定在ServletContext上,當你需要的時候,可以使用RequestContextUtils提供的靜態方法找到WebApplicationContext

Spring的DispatcherServlet有一組特殊的bean,用來處理請求和渲染相應的視圖。這些bean包含在Spring的框架里,可以在WebApplicationContext中配置,配置方式與配置其它bean相同。這些bean中的每一個都在下文作詳細描述。此刻讀者只需知道它們的存在,便繼續對DispatcherServlet進行討論。對大多數bean,Spring都提供了合理的缺省值,所以在開始階段,你不必擔心如何對其進行配置。

表 13.1. WebApplicationContext中特殊的bean

名稱 描述
控制器(Controller) 控制器 實現的是MVC中C 那個組成部分。
處理器映射(Handler mapping) 處理器映射包含預處理器(pre-processor),后處理器(post-processor)和控制器的列表,它們在符合某種條件時才被執行(例如符合控制器指定的URL)。
視圖解析器(View resolvers) 視圖解析器 可以將視圖名解析為對應的視圖。
本地化解析器(Locale resolver) 本地化解析器能夠解析用戶正在使用的本地化設置,以提供國際化視圖。
主題解析器(Theme resolver) 主題解析器能夠解析你的web應用所使用的主題,以提供個性化的布局。
上傳文件解析器(multipart file resolver) 上傳文件解析器提供HTML表單文件上傳功能。
處理器異常解析器(Handler exception resolver(s)) 處理器異常解析器可以將異常對應到視圖,或者實現更加復雜的異常處理代碼。

 

DispatcherServlet配置好以后,DispatcherServlet接收到與其對應的請求之時,處理就開始了。下面的列表描述了DispatcherServlet處理請求的全過程:

  1. 找到WebApplicationContext並將其綁定到請求的一個屬性上,以便控制器和處理鏈上的其它處理器能使用WebApplicationContext。默認的屬性名為DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE。

  2. 將本地化解析器(localResolver)綁定到請求上,這樣使得處理鏈上的處理器在處理請求(准備數據、顯示視圖等等)時能進行本地化處理。若不使用本地化解析器,也不會有任何副作用,因此如果不需要本地化解析,忽略它就可以了。

  3. 將主題解析器綁定到請求上,這樣視圖可以決定使用哪個主題。如果你不需要主題,可以忽略它。

  4. 如果上傳文件解析器被指定,Spring會檢查每個接收到的請求是否存在上傳文件,如果是,這個請求將被封裝成MultipartHttpServletRequest以便被處理鏈中的其它處理器使用。(關於文件上傳的更多內容請參考第 13.8.2 節 “使用MultipartResolver。)

  5. 找到合適的處理器,執行和這個處理器相關的執行鏈(預處理器,后處理器,控制器),以便為視圖准備模型數據。

  6. 如果模型數據被返回,就使用配置在WebApplicationContext中的視圖解析器顯示視圖,否則視圖不會被顯示。有多種原因可以導致返回的數據模型為空,比如預處理器或后處理器可能截取了請求,這可能是出於安全原因,也可能是請求已經被處理過,沒有必要再處理一次。

在請求處理過程中拋出的異常,可以被任何定義在WebApplicationContext中的異常解析器所獲取。使用這些異常解析器,你可以在異常拋出時根據需要定義特定行為。

Spring的DispatcherServlet也支持返回Servlet API定義的last-modification-date。決定某個請求最后修改的日期很簡單:DispatcherServlet會首先尋找一個合適的handler mapping,檢查從中取得指定的處理器是否實現了LastModified接口,如果是,將調用long getLastModified(request)方法,並將結果返回給客戶端。

你可以通過兩種方式定制Spring的DispatcherServlet:在web.xml文件中增加添加context參數,或servlet初始化參數。下面是目前支持的參數。

表 13.2. DispatcherServlet初始化參數

參數 描述
contextClass 實現WebApplicationContext接口的類,當前的servlet用它來創建上下文。如果這個參數沒有指定,默認使用XmlWebApplicationContext
contextConfigLocation 傳給上下文實例(由contextClass指定)的字符串,用來指定上下文的位置。這個字符串可以被分成多個字符串(使用逗號作為分隔符)來支持多個上下文(在多上下文的情況下,如果同一個bean被定義兩次,后面一個優先)。
namespace WebApplicationContext命名空間。默認值是[server-name]-servlet


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM