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