Spring MVC請求處理流程
對Web應用來說,表示層是不可或缺的重要環(huán)節(jié)。傳統(tǒng)的Struts2框架就是一個優(yōu)秀的Web框架。除了Struts2框架外,Spring框架也為表示層提供了一個優(yōu)秀的Web框架,即Spring MVC。由于Spring MVC采用了松耦合可插拔組件結構,因此比其他MVC框架具有更大的擴展性和靈活性。通過注解,Spring MVC使得POJO成為處理用戶請求的控制器,無需實現(xiàn)任何接口。
一、環(huán)境及準備
Eclipse(http://www.eclipse.org/)
Tomcat9.0.4(http://tomcat.apache.org/)
jdk9.0.4(http://www.oracle.com/technetwork/java/javase/downloads/index.html)
Spring-framework-5.0.4.RELEASE-dist.zip(http://repo.springsource.org/libs-release-local/)
二、創(chuàng)建項目
在Eclipse中,創(chuàng)建一個名為“springmvc-1”的Web項目,并把相關jar包添加到項目的WebContent\WEB-INF\lib路徑中,并添加到項目的構建路徑中。如下圖所示:
??????

項目最終的目錄結構,如下圖所示:

三、前端控制器DispatcherServlet
在web.xml文件中,配置Spring MVC的前端控制器DispatcherServlet。Spring MVC是基于Servlet的框架,DispatcherServlet是整個Spring MVC框架的核心,它負責接收請求并將其分派給相應的處理器處理,關鍵配置代碼如下:
??????

上述配置的目的在于,讓Web容器使用Spring MVC的DispatcherServlet,并通過設置url-pattern為“/”,將所有的URL請求都映射到這個前端控制器DispatcherServlet。在配置DispatcherServlet的時候,通過設置contextConfigLocation參數(shù)來指定Spring MVC配置文件的位置,此處使用Spring 資源路徑的方式進行指定。
四、創(chuàng)建Spring MVC的配置文件
在項目springmvc-1的src目錄下創(chuàng)建Spring MVC配置文件springmvc.xml,在該配置文件中,我們使用Spring MVC最簡單的配置方式進行配置,主要配置如下:
??????

在springmvc.xml配置文件中,首先要引入beans、aop、context和mvc命名空間,然后主要完成配置處理器和視圖解析器。在springmvc.xml配置文件中,并沒有配置處理器映射和處理器適配器,當用戶沒有配置這兩項時,Spring會使用默認的處理器映射和處理器適配器來處理請求。
五、創(chuàng)建Handler處理器(Controller)
? 在項目的src目錄下創(chuàng)建包com.springmvc.controller,在包中創(chuàng)建類HelloController.java,并實現(xiàn)Controller接口中的handleRequest方法,用來處理hello請求,代碼如下:
??????

上訴代碼中,HelloController是一個實現(xiàn)了Controller接口的控制器,它可以處理一個單一的請求動作。handleRequest是Controller接口必須實現(xiàn)的方法,該方法必須返回一個包含視圖名或視圖名和模型的ModelAndView對象,該對象既包含視圖信息,也包含模型數(shù)據(jù)信息。這樣Spring MVC就可以使用視圖對模型數(shù)據(jù)進行解析。本例返回的模型中包含一個名為“msg”的字符串對象,返回的視圖路徑為 /ch06/first.jsp,因此,請求將被轉發(fā)到 ch06路徑下的 first.jsp頁面。
ModelAndView對象代表Spring MVC中呈現(xiàn)視圖界面時所使用的Model(模型數(shù)據(jù))和View(邏輯視圖名稱)。由于Java一次只能返回一個對象,所以ModelAndView的作用就是封裝這兩個對象,一次返回我們所需要的Model和View。當然,返回的模型和視圖也都是可選的,在一些情況下,模型中沒有任何數(shù)據(jù),那么只返回視圖即可,或者只返回模型,讓Spring MVC根據(jù)請求URL來決定。以后還會對ModelAndView對象進行講解。
六、創(chuàng)建視圖頁面
??在項目WebContext路徑下創(chuàng)建ch06文件夾,在ch06文件夾中創(chuàng)建JSP視圖頁面first.jsp,并在該視圖頁面上通過EL表達式輸出“msg”中的信息,代碼如下:
??

七、部署項目,啟動Tomcat服務器進行測試
將項目springmvc-1發(fā)布到Tomcat中,并啟動Tomcat服務器,在瀏覽器地址中訪問http://localhost:8080/springmvc-1/hello,其運行效果如下圖所示:

從上圖可以看到,瀏覽器中已經(jīng)顯示出了模型對象的字符串信息,控制臺窗口中輸出了“Hello Springmvc_1”提示,這也就說明程序執(zhí)行成功。
使用MVC框架就應該遵守MVC思想,MVC框架不贊成瀏覽器直接訪問Web應用的視圖頁面,用戶的所有請求都只應向控制器發(fā)送,由控制器調用模型組件、視圖組件向用戶呈現(xiàn)數(shù)據(jù)。
八、總結
當用戶發(fā)送URL請求http://localhost:8080/springmvc-1/hello時,根據(jù)web.xml中對DispatcherServlet(前端控制器)的配置,該請求被DispatcherServlet(前端控制器)截獲,并根據(jù)HandleMapping(處理器映射器)找到處理相應請求的Handler處理器(Controller控制器,這里便是HelloController);Controller處理完成后,返回ModelAndView對象;該對象告訴DispatcherServlet(前端控制器)需要通過哪個視圖來進行數(shù)據(jù)模型的展示,DispatcherServlet(前端控制器)根據(jù)視圖解析器把Controller返回的邏輯視圖名渲染成真正的視圖并輸出,呈現(xiàn)給用戶。
九、深入了解Spring MVC請求處理流程
? Spring MVC請求處理流程如下圖所示,我們一步一步來看它的處理流程。
??

(1)用戶通過客戶端向服務器發(fā)起一個request請求,此請求會被前端控制器(DispatcherServlet)攔截。
(2)前端控制器(DispatcherServlet)請求處理器映射器(HandleMapping)去查找處理器(Handler),可以依據(jù)XML配置或注解去查找。
(3)處理器映射器(HandleMapping)根據(jù)請求的URL找到具體的處理器(Handler),生成處理器對象及處理器攔截器(如果有則生成),并返回給前端控制器。
(4)前端控制器(DispatcherServlet)請求處理器適配器(HandlerAdapter)去執(zhí)行相應的處理器(Handler,常稱為Controller)。
(5)處理器適配器(HandlerAdapter)會調用并執(zhí)行處理器(Handler),這里的處理器(Handler)指的是程序中編寫的Controller類,也被稱為后端控制器。請求信息在真正到達處理器(Handler)的處理方法之前的這段時間內,Spring MVC還完成了很多工作。
消息轉換:將請求消息(如Json、xml等數(shù)據(jù))轉換成一個對象,將對象轉換為指定的響應信息。
數(shù)據(jù)轉換:對請求消息進行數(shù)據(jù)轉換,如String轉換成Integer、Double等。
數(shù)據(jù)格式化:對請求消息進行數(shù)據(jù)格式化,如將字符串轉換成格式化數(shù)字或格式化日期等。
數(shù)據(jù)驗證:驗證數(shù)據(jù)的有效性(長度、格式等),驗證結果存儲到BindingResult或Error中。
(6)處理器(Handler)執(zhí)行完畢后,也就是Controller執(zhí)行完畢后,會返回給處理器適配器(HandlerAdapter)一個ModelAndView對象(Spring MVC底層對象),該對象中會包含View視圖信息或包含View視圖信息和Model數(shù)據(jù)模型信息。
(7)處理器適配器(HandlerAdapter)接收到ModelAndView對象后,將其返回給前端控制器(DispatcherServlet)。
(8)前端控制器(DispatcherServlet)接收到ModelAndView對象后,選擇一個合適的視圖解析器(ViewReslover)對視圖進行解析。
(9)視圖解析器(ViewReslover)解析后,會根據(jù)View視圖信息配置到相應的視圖結果,反饋給前端控制器(DispatcherServlet)。
(10)前端控制器(DispatcherServlet)收到View視圖后,進行視圖渲染,將模型數(shù)據(jù)(在ModelAndView對象中)填充到request域。
(11)前端控制器(DispatcherServlet)向用戶響應結果。
以上就是Spring MVC的整個請求處理流程,其中用到的組件有前端控制器(DispatcherServlet)、處理器映射器(HandleMapping)、處理器適配器(HandlerAdapter)、Handler處理器(Controller)、視圖解析器(ViewReslover)、視圖(View)。其中,前端控制器(DispatcherServlet)、處理器映射器(HandleMapping)、處理器映射器(HandleMapping)、視圖解析器(ViewReslover)對象的工作是在框架內部執(zhí)行的,開發(fā)人員并不需要關心這些對象內部的實現(xiàn)過程,只需要配置前端控制器(DispatcherServlet),完成Handler處理器(Controller)中的業(yè)務處理,并在視圖(View)中展示相應信息即可。
