?
本文檔使用 PHP中文網(wǎng)手冊 發(fā)布
與其它web MVC框架一樣,Spring的web MVC框架是一個請求驅(qū)動的web框架,其設(shè)計圍繞一個中心的servlet進行,
它能將請求分發(fā)給控制器,并提供其它功能幫助web應(yīng)用開發(fā)。然而,Spring的DispatcherServlet
所做的不僅僅是這些,它和Spring的IoC容器完全集成在一起,從而允許你使用Spring的其它功能。
下圖展示了Spring Web MVC DispatcherServlet
處理請求的流程。
熟悉設(shè)計模式的讀者可能會發(fā)現(xiàn)DispatcherServlet
應(yīng)用了“
Front Controller”模式(很多其他的主流web框架也都用到了該模式)。
Spring Web MVC請求處理流程
DispatcherServlet
實際上是一個Servlet
(它繼承了HttpServlet
)。與其它Servlet一樣,
DispatcherServlet
定義在web應(yīng)用的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
結(jié)尾的請求都會由名為
example
的DispatcherServlet
處理。這只是配置Spring Web MVC
的第一步。接下來需要配置DispatcherServlet
本身和Spring Web MVC 框架用到的其他的bean。
正如在第?3.8?節(jié) “The ApplicationContext
”中所描述的,Spring中的
ApplicationContext
實例可以被限制在不同的作用域(scope)中。在web MVC框架中,每個
DispatcherServlet
有它自己的WebApplicationContext
,這個context繼承了根 WebApplicationContext
的所有bean定義。這些繼承的bean也可以在每個serlvet自己的所屬的域中被覆蓋(override),覆蓋后的bean
可以被設(shè)置成只有這個servlet實例自己才可以使用的屬性。
Spring Web MVC中的Context體系
在DispatcherServlet
的初始化過程中,框架會在web應(yīng)用的
WEB-INF
文件夾下尋找名為[servlet-name]-servlet.xml
的配置文件,生成文件中定義的bean。這些bean會覆蓋在全局范圍(global cope)中定義的同名的bean。
下面這個例子展示了在web.xml
中DispatcherServlet
的配置:
<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這個文件應(yīng)該聲明在
Spring Web MVC 框架中需要的bean。 這個文件的路徑也可以通過web.xml中servlet
的初始化參數(shù)來更改(詳情見下面的例子)。
WebApplicationContext
僅僅是一個擁有web應(yīng)用必要功能的普通
ApplicationContext
。它與一個標(biāo)準(zhǔn)的
ApplicationContext
的不同之處在于,它能夠解析theme
(參考第?13.7?節(jié) “使用主題”),并且它知道自己與哪個servlet相關(guān)聯(lián)
(通過ServletContext
)。WebApplicationContext
被綁定在ServletContext
上,需要時,可以使用
RequestContextUtils
提供的靜態(tài)方法找到WebApplicationContext
。
Spring的DispatcherServlet
有一組特殊的bean,
用來處理請求和渲染相應(yīng)的視圖。這些bean包含在Spring的框架里,可以在
WebApplicationContext
中配置,配置方式與配置其它bean相同。這些bean
中的每一個都在下文作詳細(xì)描述。此刻讀者只需知道它們的存在,以便我們繼續(xù)對DispatcherServlet
進行討論。對大多數(shù)bean,Spring都提供了合理的缺省值,所以在開始階段,你不必?fù)?dān)心如何對其進行配置。
表?13.1.?WebApplicationContext
中特殊的bean
Bean類型 | 描述 |
---|---|
控制器(Controllers) |
控制器 實現(xiàn)的是MVC中的C 。
|
處理器映射(Handler mapping) | 處理器映射包含預(yù)處理器(pre-processor), 后置處理器(post-processor)和控制器的列表,它們在符合某種條件時才被執(zhí)行(例如符合控制器指定的URL)。 |
視圖解析器(View resolvers) | 視圖解析器 可以將視圖名解析為對應(yīng)的視圖。 |
本地化解析器(Locale resolver) | 本地化解析器能夠解析用戶正在使用的本地化設(shè)置,以提供國際化視圖。 |
主題解析器(Theme resolver) | 主題解析器能夠解析你的web應(yīng)用所使用的主題,以提供個性化的布局。 |
文件上傳解析器(Multipart File resolver) | 文件上傳解析器提供HTML表單文件上傳功能。 |
處理器異常解析器(Handler exception resolver(s)) | 處理器異常解析器可以將異常對應(yīng)到視圖,或者實現(xiàn)更加復(fù)雜的異常處理邏輯。 |
DispatcherServlet
配置完成后,當(dāng)相應(yīng)的請求到達時,處理就開始了。
下面的列表描述了DispatcherServlet
處理請求的全過程:
找到WebApplicationContext
并將其綁定到請求的一個屬性上,
以便控制器和處理鏈上的其它處理器能使用WebApplicationContext
。
默認(rèn)的屬性名為DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE
。
將本地化解析器(localResolver)綁定到請求上,這樣使得處理鏈上的處理器在處理請求(準(zhǔn)備數(shù)據(jù)、顯示視圖等等) 時能進行本地化處理。若不使用本地化解析器,也不會有任何副作用,因此如果不需要本地化解析,忽略它即可。
將主題解析器綁定到請求上,這樣視圖可以決定使用哪個主題。如果你不需要主題,可以忽略它,不會有任何影響。
如果上傳文件解析器被指定,Spring會檢查每個接收到的請求是否存在上傳文件,如果存在,
這個請求將被封裝成MultipartHttpServletRequest
以便被處理鏈中的其它處理器使用
(關(guān)于文件上傳的更多內(nèi)容請參考第?13.8.2?節(jié) “使用MultipartResolver
”)。
找到合適的處理器,執(zhí)行和這個處理器相關(guān)的執(zhí)行鏈(預(yù)處理器,后置處理器,控制器),以便為視圖準(zhǔn)備模型數(shù)據(jù)(用于渲染)。
如果模型數(shù)據(jù)被返回,就使用配置在WebApplicationContext
中的視圖解析器顯示視圖,
否則視圖不會被顯示。有多種原因可以導(dǎo)致返回的數(shù)據(jù)模型為空,比如預(yù)處理器或后處理器可能截取了請求,這可能是出于安全原因,
也可能是請求已經(jīng)被處理,沒有必要再處理一次。
請求處理過程中拋出的異常,可以被任何定義在WebApplicationContext
中的異常解析器所獲取。
使用這些異常解析器,可以在異常拋出時根據(jù)需要定義特定行為。
Spring的DispatcherServlet
也支持返回Servlet API定義的last-modification-date。
決定某個請求的最后修改日期很簡單:DispatcherServlet
會首先尋找一個合適的handler mapping,檢查從中取得指定的處理器是否實現(xiàn)了
LastModified
接口,如果是,將調(diào)用long getLastModified(request)
方法,并將結(jié)果返回給客戶端。
可以通過兩種方式定制Spring的DispatcherServlet
:在web.xml
文件中增加添加context參數(shù),
或servlet初始化參數(shù)。下面是可能用到的參數(shù)。
表?13.2.?DispatcherServlet
初始化參數(shù)
參數(shù) | 描述 |
---|---|
contextClass |
實現(xiàn)WebApplicationContext 接口的類,當(dāng)前的servlet用它來創(chuàng)建上下文。如果這個參數(shù)沒有指定,
默認(rèn)使用XmlWebApplicationContext 。
|
contextConfigLocation |
傳給上下文實例(由contextClass指定)的字符串,用來指定上下文的位置。這個字符串可以被分成多個字符串(使用逗號作為分隔符) 來支持多個上下文(在多上下文的情況下,如果同一個bean被定義兩次,后面一個優(yōu)先)。 |
namespace |
WebApplicationContext 命名空間。默認(rèn)值是[server-name]-servlet 。
|