第一章:Spring Web MVC入門——深入淺出學Spring Web MVC

Spring Web MVC是什麼和能幹什麼

 Spring Web MVC是什麼
是一種輕量級的、基於MVC的 Web應用框架    
 Spring Web MVC能做什麼
√進行更簡潔的Web層的開發;
√天生與Spring框架集成(如IoC容器、AOP等);
√提供強大的約定大於配置的契約式編程支持;
√能簡單的進行Web層的單元測試;
√支持靈活的URL到頁面控制器的映射;
√非常容易與其他視圖技術集成,如Velocity、FreeMarker等等,因爲模型數據放在一個Model裏(Map數據結構實現,因此很容易被其他框架使用);
√非常靈活的數據驗證、格式化和數據綁定機制
√提供一套強大的JSP標籤庫,簡化JSP開發;
√支持靈活的本地化、主題等解析;
√更加簡單的異常處理;
√對靜態資源的支持;
√支持Restful風格

Spring Web MVC有什麼

Spring Web MVC使用了MVC架構模式的思想,將web層進行職責解耦。同樣也是基於請求驅動的,也就是使用請求-響應模型。它主要包含如下組件:
DispatcherServlet :前端控制器
Handler Mapping :將請求映射到處理器
HandlerAdapter :把處理器包裝爲適配器,用來支持多種類型的處理器
View Resolver :視圖解析器
Controller接口 :頁面控制器/動作/處理器
LocalResolver:本地化解析,因爲Spring支持國際化,因此LocalResolver解析客戶端的Locale信息從而方便進行國際化
ThemeResovler:主題解析,通過它來實現一個頁面多套風格,即常見的類似於軟件皮膚效果
MultipartResolver:文件上傳解析,用於支持文件上傳
HandlerExceptionResolver :解析並處理異
RequestToViewNameTranslator:當處理器沒有返回邏輯視圖名等相關信息時,自動將請求URL映射爲邏輯視圖名
FlashMapManager:用於管理FlashMap的策略接口,FlashMap用於存儲一個請求的輸出,當進入另一個請求時作爲該請求的輸入,通常用於重定向場景

Spring Web MVC的優勢

清晰的角色劃分:前端控制器(DispatcherServlet)、請求到處理器映射(HandlerMapping)、處理器適配器(HandlerAdapter)、視圖解析器(ViewResolver)、處理器或頁面控制器(Controller)、驗證器(Validator)、命令對象(Command  請求參數綁定到的對象就叫命令對象)、表單對象(Form Object 提供給表單展示和提交到的對象就叫表單對象)
分工明確,而且擴展點相當靈活,可以很容易擴展,雖然幾乎不需要
由於命令對象就是一個POJO,無需繼承框架特定API,可以使用命令對象直接作爲業務對象
和Spring 其他框架無縫集成,是其它Web框架所不具備的
可適配,通過HandlerAdapter可以支持任意的類作爲處理器
可定製性,HandlerMapping、ViewResolver等能夠非常簡單的定製
功能強大的數據驗證、格式化、綁定機制
利用Spring提供的Mock對象能夠非常簡單的進行Web層單元測試
本地化、主題的解析的支持,使我們更容易進行國際化和主題的切換
強大的JSP標籤庫,使JSP編寫更容易
………………還有比如RESTful風格的支持、簡單的文件上傳、約定大於配置的契約式編程支持、基於註解的零配置支持等等。

HelloWorld

準備開發環境和運行環境
☆開發工具:  eclipse
☆運行環境:  apache-tomcat-7.0.4
☆工程:動態  web  工程
☆  Spring  框架下載:
spring-framework-3.2.3.RELEASE-dist.zip
☆依賴  jar  包:
Spring框架jar包:
將spring-framework-3.2.3.RELEASE-dist.zip/libs/下的所有jar包,去掉XXX-javadoc.jar,還有去掉XXX-sources.jar,剩下的拷貝到項目的WEB-INF/lib目錄下
Spring框架依賴的jar包:
需要添加Apache commons logging日誌,此處使用的是commons.logging-1.1.1.jar;當然還需要引入tomcat/lib裏面的servlet-api.jar
需要添加jstl標籤庫支持,此處使用的是jstl-1.2.jar和standard-1.1.2.jar;


前端控制器的配置
在web.xml中添加如下配置:

java代碼:
  1.    <servlet>  
  2.        <servlet-name>springmvc</servlet-name>  
  3. <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  4.        <load-on-startup>1</load-on-startup>  
  5.    </servlet>  
  6.    <servlet-mapping>  
  7.        <servlet-name>springmvc</servlet-name>  
  8.        <url-pattern>/</url-pattern>  
  9.    </servlet-mapping>  

load-on-startup:表示啓動容器時初始化該Servlet;
url-pattern:表示哪些請求交給Spring Web MVC處理,“/” 是用來定義默認servlet映射的。也可以如“*.html”表示攔截所有以html爲擴展名的請求。
自此請求已交給SpringMVC框架處理,因此還需要配置Spring的配置文件,默認DispatcherServlet會加載WEB-INF/[DispatcherServlet的Servlet名字]-servlet.xml配置文件。本示例爲WEB-INF/ springmvc-servlet.xml。
 
在Spring配置文件中配置HandlerMapping、HandlerAdapter
本示例在WEB-INF/springmvc-servlet.xml文件中:

java代碼:
  1. <!-- HandlerMapping -->  
  2. <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>  
  3. <!-- HandlerAdapter -->  
  4. <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>      

BeanNameUrlHandlerMapping  :
表示將請求的URL和Bean名字映射,如URL爲 “上下文/hello”,則Spring配置文件必須有一個名字爲“/hello”的Bean,上下文默認忽略。
SimpleControllerHandlerAdapter  :
表示所有實現了org.springframework.web.servlet.mvc.Controller接口的Bean可以作爲Spring Web MVC中的處理器。如果需要其他類型的處理器可以通過實現HadlerAdapter來解決。
 
在Spring配置文件中配置ViewResolver
本示例在WEB-INF/springmvc-servlet.xml文件中:

java代碼:
  1. <!-- ViewResolver -->  
  2. <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
  3.     <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>  
  4.     <property name="prefix" value="/WEB-INF/jsp/"/>  
  5.     <property name="suffix" value=".jsp"/>  
  6. </bean>  
 
InternalResourceViewResolver :用於支持Servlet、JSP視圖解析;
     viewClass :JstlView表示JSP模板頁面需要使用JSTL標籤庫,classpath中必須包含jstl的相關jar包;
     prefix 和 suffix :查找視圖頁面的前綴和後綴(前綴[邏輯視圖名]後綴),比如傳進來的邏輯視圖名爲hello,則該該jsp視圖頁面應該存放在“WEB-INF/jsp/hello.jsp”
 
 
開發處理器/頁面控制器

java代碼:
  1. public class HelloWorldController implements Controller {  
  2.     @Override  
  3.     public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse resp) throws Exception {  
  4.         //1、收集參數、驗證參數  
  5.         //2、綁定參數到命令對象  
  6.         //3、將命令對象傳入業務對象進行業務處理  
  7.         //4、選擇下一個頁面  
  8.         ModelAndView mv = new ModelAndView();  
  9.         //添加模型數據 可以是任意的POJO對象  
  10.         mv.addObject("message""Hello World!");  
  11.         //設置邏輯視圖名,視圖解析器會根據該名字解析到具體的視圖頁面  
  12.         mv.setViewName("hello");  
  13.         return mv;  
  14.     }  
  15. }  

 
org.springframework.web.servlet.mvc.Controller
頁面控制器/處理器必須實現Controller接口,注意別選錯了;後邊我們會學習其他的處理器實現方式;比如註解的方式。
public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse resp) :
功能處理方法,實現相應的功能處理,比如收集參數、驗證參數、綁定參數到命令對象、將命令對象傳入業務對象進行業務處理、最後返回ModelAndView對象;
ModelAndView:包含了視圖要實現的模型數據和邏輯視圖名
“mv.addObject("message", "Hello World!");”表示添加模型數據,此處可以是任意POJO對象;“mv.setViewName("hello");”表示設置邏輯視圖名爲“hello”,視圖解析器會將其解析爲具體的視圖,如前邊的視圖解析器InternalResourceViewResolver會將其解析爲“WEB-INF/jsp/hello.jsp”
 
把HelloWorldController配置成爲Spring的Bean
需要將其添加到Spring配置文件(WEB-INF/chapter2-servlet.xml),讓其接受Spring IoC容器管理:
<!-- 處理器 -->
<bean name= "/hello"class= "cn.javass.springmvc.hello.HelloWorldController"/>

name= “ /hello ” :
前邊配置的BeanNameUrlHandlerMapping,表示如過請求的URL爲 “上下文/hello”,則將會交給該Bean進行處理。
開發視圖頁面, 來個最簡單的,放到WEB-INF/jsp/hello.jsp
<%@ page language= "java" contentType= "text/html; charset=UTF-8"pageEncoding= "UTF-8"%>
${message}
啓動服務器運行測試
通過請求: http://localhost:9080/mvcexample/hello,如果頁面輸出“Hello World! ”就表明成功了!
 

Spring Web MVC處理請求的流程

 
 
具體執行步驟如下:
1、首先用戶發送請求——>前端控制器,前端控制器根據請求信息(如URL)來決定選擇哪一個頁面控制器進行處理並把請求委託給它,即以前的控制器的控制邏輯部分;圖中的1、2步驟;
 
2、頁面控制器接收到請求後,進行功能處理,首先需要收集和綁定請求參數到一個對象,這個對象在Spring Web MVC中叫命令對象,並進行驗證,然後將命令對象委託給業務對象進行處理;處理完畢後返回一個ModelAndView(模型數據和邏輯視圖名);圖中的3、4、5步驟;
 
3、前端控制器收回控制權,然後根據返回的邏輯視圖名,選擇相應的視圖進行渲染,並把模型數據傳入以便視圖渲染;圖中的步驟6、7;
 
4、前端控制器再次收回控制權,將響應返回給用戶,圖中的步驟8;至此整個處理流程結束。
 

Spring Web MVC的核心架構

 

1、用戶發送請求—>DispatcherServlet,前端控制器收到請求後自己不進行處理,而是委託給其他的解析器進行處理,作爲統一訪問點,進行全局的流程控制;
 
2、DispatcherServlet—>HandlerMapping, HandlerMapping將會把請求映射爲HandlerExecutionChain對象(包含一個Handler處理器(頁面控制器)對象、多個HandlerInterceptor攔截器)對象;
 
3、DispatcherServlet—>HandlerAdapter,HandlerAdapter將會把處理器包裝爲適配器,從而支持多種類型的處理器;
 
4、HandlerAdapter—>處理器功能處理方法的調用,HandlerAdapter將會根據適配的結果調用真正的處理器的功能處理方法,完成功能處理;並返回一個ModelAndView對象(包含模型數據、邏輯視圖名);
 
5、ModelAndView的邏輯視圖名—> ViewResolver, ViewResolver將把邏輯視圖名解析爲具體的View;
 
6、View—>渲染,View會根據傳進來的Model模型數據進行渲染,此處的Model實際是一個Map數據結構,因此很容易支持其他視圖技術;
 
7、返回控制權給DispatcherServlet,由DispatcherServlet返回響應給用戶,到此一個流程結束。
 
此處我們只是講了核心流程,沒有考慮攔截器、本地解析、文件上傳解析等,後邊再細述。
 

 

HelloWorld運行流程分析

1、首先用戶發送請求http://localhost:9080/mvcexaple/hello—>web容器,web容器根據“/hello”路徑映射到DispatcherServlet(url-pattern爲/)進行處理;
 
2、DispatcherServlet—>BeanNameUrlHandlerMapping進行請求到處理的映射,BeanNameUrlHandlerMapping將“/hello”路徑直接映射到名字爲“/hello”的Bean進行處理,即HelloWorldController,BeanNameUrlHandlerMapping將其包裝爲HandlerExecutionChain(只包括HelloWorldController處理器,沒有攔截器)
 
3、DispatcherServlet—> SimpleControllerHandlerAdapter將HandlerExecutionChain中的處理器(HelloWorldController)適配爲SimpleControllerHandlerAdapter;
 
4、SimpleControllerHandlerAdapter—> HelloWorldController處理器功能處理方法的調用,SimpleControllerHandlerAdapter將會調用處理器的handleRequest方法進行功能處理,該處理方法返回一個ModelAndView給DispatcherServlet
 
5、hello(ModelAndView的邏輯視圖名)—>InternalResourceViewResolver, InternalResourceViewResolver使用JstlView,具體視圖頁面在/WEB-INF/jsp/hello.jsp;
 
6、JstlView(/WEB-INF/jsp/hello.jsp)—>進行頁面渲染,將在處理器傳入的模型數據(message=HelloWorld!)在視圖中展示出來;
 
7、返回控制權給DispatcherServlet,由DispatcherServlet返回響應給用戶,到此一個流程結束。
POST中文亂碼解決方案 
nSpring Web MVC提供了Filter用於解決POST方式造成的中文亂碼問題,具體配置如下:
<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>utf-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping> 
建議項目及所有頁面的編碼均爲UTF-8
地址:http://sishuok.com/forum/blogPost/list/6984.html
發佈了62 篇原創文章 · 獲贊 138 · 訪問量 30萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章