Spring MVC 的優勢以及開發流程
Spring MVC優勢:
- 擁有強大的靈活性、非侵入性和可配置性
- 提供了一個前端控制器DispatcherServlet,開發者無需額外開發控制器物件
- 分工明確,包括控制器、驗證器、命令物件、模型物件、處理程式對映檢視解析器等等,每一個功能實現由一個專門的物件負責完成
- 可以自動繫結使用者輸入,並正確的轉換資料型別。例如SpringMVC能自動解析字串,並將其設定為模型的int或者float型別的屬性
- 使用一個key/value的map物件實現更加靈活的模型資料傳輸
- SpringMVC內建了常見的校驗器,可以校驗使用者輸入,如果校驗不通過,則重定向回輸入表單。輸入校驗是可選的,並且支援程式設計方式以及宣告方式
- 支援國際化
- 支援多種檢視技術,最常見的是JSP和Velocity和FreeMaker
- Spring提供了一個簡單而強大的JSP標籤庫,支援資料繫結功能,使得編寫JSP頁面更加容易
一個小回顧
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd" >
<!--配置controller,對映/hello.do請求-->
<bean name="/hello.do" class="com.cskaoyan.controller.FirstController"/>
<!--根據Bean的名字去做url對映的 對映器-->
<!--處理對映器將Bean的name作為url進行查詢,需要在截止controller時指定name(url)-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
<!--處理器介面卡,專門去適配一個特定的controller,所有處理介面卡都要實現HandlerAdapter介面-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!--檢視解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"/>
</beans>
TIP
SpringMVC 建議把所有的檢視頁面存放在WEB-INF資料夾下,這樣可以保護檢視頁面,避免直接向檢視頁面(jsp等)傳送請求,而是由實現了Controller介面的自定義控制器來呈現。
使用MVC框架就應該嚴格遵守MVC思想。MVC框架不贊成瀏覽器直接訪問Web應用的檢視頁面,使用者的所有請求都應該只向Controller傳送,由Controller呼叫(Dao&Bean)/view向用戶呈現資料
- 註解配置MVC
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--spring可以自動去掃描base-pack下面的包或者子包下面的Java檔案,如果掃描到有
Spring的相關注解的類,則把這些類註冊為Spring的bean-->
<context:component-scan base-package="com.bamzhy"/>
<!--配置Annotation型別的處理對映器,根據請求查詢對映-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<!--配置Annotation型別的處理器介面卡,完成@RequestMapping標註方法的呼叫-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
<!--檢視解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"/>
</beans>
- 這個是最方便方法
<context:component-scan base-package="com.bamzhy"/>
<!--註解驅動:替我們自動配置最新版的註解的處理器對映器和處理器介面卡-->
<mvc:annotation-driven></mvc:annotation-driven>
SpringMVC執行的流程
Spring MVC的開發步驟
- 在web.xml中定義前端控制器DispatcherServlet來攔截使用者請求,由於web應用時基於請求/響應架構的應用,所以不管哪個MVC web框架都需要在Web.xml中配置該框架的核心servlet或者filter,這樣才可以讓該框架介入web應用中。
- 如果需要以post方式提交請求,則定義包含表單資料的JSP頁面。如果僅僅是以get方式傳送請求,則無需經過這一步。
- 定義處理使用者請求的Handler類,可以實現Controller介面或者使用@ controller註解。
Tip
Controller並未接收到使用者請求,它怎麼能夠處理使用者的請求呢?MVC框架的底層機制是:前端Servlet接收到使用者請求後,通常會對使用者請求進行簡單的預處理,例如解析、封裝引數等等,然後通過反射來建立controller例項,並呼叫Controller的指定方法(**實現Controller介面的handleRequest方法,而基於註解的控制器可以是任意方法**)
當Servlet攔截使用者請求以後,它如何知道建立哪個Controller介面的例項呢?
- 利用xml檔案:例如在xml檔案中描述haha請求對應使用FirstController類。
利用註解:例如使用@ Controller描述一個類,並且使用註解 @ requestMapping(value=”/haha”)描述haha請求對應的方法。
在Spring MVC 框架中,控制器實際上由兩個部分共同組成,即攔截所有使用者請求和處理請求的通用程式碼都有前端控制器DispatcherServlet完成,而實際的業務控制(例如呼叫後臺業務邏輯程式碼,返回處理結果等)都由Controller處理
Java領域的絕大部分MVC框架都很喜歡使用xml問價你來進行配置管理,即配置哪個請求對應哪個Controller進行處理,從而讓前端控制器根據該配置來建立合適的Controller例項,並且呼叫該Controller的業務控制方法。
< bean name=”/haha” class=”com.bamzhy.controller.MyFirstServlet” >
現在大多使用配置來實現。
現在幾乎所有MVC礦建都使用約定優於配置的思想,也就是採用約定方式來規定使用者請求地址和Handle之間的對應關係(用註解)。當Controller處理使用者請求結束後,通常會返回一個ModelAndView物件,該物件中應該包含返回的view名或者view名和model,這個view名就代表需要顯示的物理檢視資源。如果controller需要把一些資料傳給檢視資源,則可以通過模型物件。
Spring MVC的完整請求流程
1、使用者向伺服器傳送請求,請求被DispatcherServlet截獲
2、DispatcherServlet對請求的URL(統一資源定位符)進行解析,得到URI(請求資源識別符號)。根據URI呼叫HandlerMapping獲得該Handler配置的所有相關的物件,包括Handler物件以及Handler物件對應的攔截器,這些物件會被封裝到一個HandlerExecutionChain物件中返回
3、DispatcherServlet根據獲得Handler選擇一個合適的HandlerAdaper。HandlerAdaper的設計符合面向物件中的單一職責原則,程式碼架構清晰,便於維護,最重要的是diamante可複用性高。HandlerAdaper會被用於處理多種Handler,呼叫Handler實際處理請求的方法.
4、提取請求中的模型資料,開始執行Handler,在填充Handler的入參過程中,根據配置,Spring將幫你做一些額外的工作。
訊息轉換 :將請求訊息如Json、xml資料轉換成一個物件,將物件轉換為指定的響應資訊。
資料轉換:對請求訊息進行資料轉換,比如String轉換成Integer、Double等
資料格式化:對請求訊息進行資料格式化,如將字串轉換成格式化數字或者格式化日期等
資料驗證:驗證資料的有效性(長度格式等)驗證結果儲存到BindingResult或Error中
5、Handler執行完成後,向DispatcherServlet返回一個ModelAndView物件,ModelAndVIew物件彙總應該包含檢視名或者檢視+模型
6、根據返回的ModelAndView物件,選擇一個合適的ViewResolver(檢視解析器)返回給DispatcherServlet
7、ViewResolver結合Model和view來渲染檢視
8、將檢視渲染結果返回給客戶端