SpringMVC應用的開發步驟
1.在web.xml文件中定義前端控制器DispatcherServlet來攔截用戶請求。在web.xml中配置該框架的核心Servlet或Filter,這樣才可以讓該框架接入web應用中。
例如,開發SpringMVC應用的第1步就是在web.xml文件中增加如下配置片段:
<!-- 定義Spring MVC的前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/springmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 讓Spring MVC的前端控制器攔截所有請求 -->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
2.如果需要以post方式提交請求,則定義包含表單數據的JSP頁面。如果僅僅只是以get方式發送請求,則無須經過這一步。
3.定義處理用戶請求的Handle類,可以實現Controller接口或使用@Controller注解。
這一步也是所有MVC框架中必不可少的,因為這個DispatcherServlet就是MVC中的C,也就是前端控制器,該控制器負責接收請求,並將請求分發給對應的Handle,即實現Controller接口的Java類,而該Java類負責調用后台業務邏輯代碼來處理請求。
MVC框架的底層機制是:前端Servlet接收到用戶請求后,通常會對用戶請求進行簡單預處理,例如解析、封裝參數等,然后通過反射來創建Controller實例,並調用Controller的指定方法(實現Controller接口的是handleRequest方法,而使用基於注解的控制器可以任意方法)來處理用戶請求。
當Servlet攔截用戶請求后,有兩種解決方案來知道創建哪個Controller接口的實例。1):利用xml配置文件,例如在xml配置文件中描述hello請求對應使用HelloController類。這就可以讓MVC框架知道創建哪個Controller接口的實例。2)利用注解,例如使用注解@Controller描述一個類,並使用注解@RequestMapping(value="/hello")描述hello請求對應的方法。這樣也可以讓MVC框架知道創建哪個Controller接口的實例並調用哪個方法處理請求。
在SpringMVC框架中,控制器實際上由兩個部分共同組成,即攔截所有用戶請求和處理請求的通用代碼都由前端控制器DispatcherServlet完成,而實際的業務控制(諸如調用后台業務邏輯代碼,返回處理結果等)則由Controller處理。
4.配置Handle。Java領域的絕大部分MVC框架都非常喜歡使用xml文件來進行配置管理,這在以前是一種思維定勢。即配置哪個請求對應哪個Controller進行處理,從而讓前端控制器根據該配置來創建合適的Controller實例,並調用該Controller的業務控制方法。
例如,可以采用如下代碼片段來配置Handle:
<!--配置Handle,映射“/hello”請求-->
<bean name="/hello" class="org.fkit.controller.HelloController"/>
在Spring2.5之后,推薦使用注解來配置Handle:
@Controller
public class HelloController{
@RequestMapping(value="/hello")
public ModelAndView hello(){
...
}
}
上面的配置片段指定如果用戶請求URL為hello,則使用org.fkit.controller.HelloController來處理。現在幾乎所有的框架都使用“約定優於配置”的思想,也就是采用約定方式來規定用戶請求地址和Handle之間的對應關系。
5.編寫視圖資源
當Handle處理用戶請求結束后,通常會返回一個ModelAndView對象,該對象中應該包含的視圖名和模型,這個視圖名就代表需要顯示的物理視圖資源。如果Handle需要把一些數據傳給視圖資源,則可以通過模型對象。
經過上面的5個步驟,即可基本完成一個SpringMVC處理流程的開發,也就是可以執行一次完整的請求->響應過程。
SpringMVC請求->響應的完整工作流程如下:
1.用戶向服務器發送請求,請求被Spring的前端控制器DispatcherServlet截獲。
2.DispatcherServlet對請求URL(統一資源定位符)進行解析,得到URI(請求資源標識符)。然后根據該URI,調用HandlerMapping獲得該Handler配置的所有的相關的對象,包括Handler對象以及Handler對象對應的攔截器,這寫對象會被封裝到一個HandlerExecutionChain對象當中返回。
3.DispatcherServlet根據獲得的Handler,選擇一個合適的HandlerAdapter。HandlerAdapter的設計符合面對對象中的單一職責原則,代碼架構清晰,便於維護,最重要的是,代碼可復用性高。HandlerAdapter會被用於處理多種Handler,調用Handler實際處理請求的方法,例如hello方法。
4.提取請求中的模型數據,開始執行Handler(Controller)。在填充Handler的入參過程中,根據配置,Spring將幫你做一些額外的工作。
消息轉換:將請求消息(如Json、xml等數據)轉換為一個對象,將對象轉換為指定的響應信息。
數據轉換:對請求消息進行數據轉換,如String轉換成Integer、Double等。
數據格式化:對請求消息進行數據格式化,如將字符串轉換為格式化數字或格式化日期等。
數據驗證:驗證數據的有效性(長度、格式等),驗證結果存儲到BindingResult或Error中。
5.Handler執行完成后,DispatcherServlet返回一個ModelAndView對象,ModelAndView對象中應該包含視圖名或視圖名和模型。
6.根據返回的ModelAndView對象,選擇一個合適的ViewReslover(視圖解析器)返回給DispatcherServlet。
7.ViewReslover結合Model和View來渲染視圖。
8.將視圖渲染結果返回給客戶端。
以上8個步驟,DispatcherServlet、HandlerMapping、HandlerAdapter和ViewResolver等對象協同工作,完成SpringMVC請求->響應的整個工作流程,這些對象所完成的工作對於開發者來說都是不可見的,開發者並不需要關心這些對象如何工作,只需要在Handler(Controller)當中完成對請求的業務處理。
對於MVC框架,控制器(Controller)執行業務邏輯,用戶產生模型數據(Model),而視圖(View)則用於渲染模型數據。如何將模型數據傳遞給視圖是SpringMVC框架的一項工作,SpringMVC提供了多種途徑輸出模型數據,如:Model和ModelMap,ModelAndView、@ModelAttribute、@SessionAttributes。
關於spingmvc-config.xml文件,最基本的有兩步:
step1:
<!-- spring可以自動去掃描base-pack下面的包或者子包下面的java文件,
如果掃描到有Spring的相關注解的類,則把這些類注冊為Spring的bean -->
<context:component-scan base-package="org.fkit.controller"/>
step2(視圖解析器):
<!-- 視圖解析器 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前綴 -->
<property name="prefix">
<value>/WEB-INF/content/</value>
</property>
<!-- 后綴 -->
<property name="suffix">
<value>.jsp</value>
</property>
</bean>