【轉】Spring MVC 教程,快速入門,深刻分析

資源下載:css

Spring_MVC_教程_快速入門_深刻分析V1.1.pdfhtml

SpringMVC核心配置文件示例.rarjava

 

 

做者:趙磊程序員

博客:http://elf8848.iteye.comweb

 

目錄 

1、前言
2、spring mvc 核心類與接口
3、spring mvc 核心流程圖ajax

4、spring mvc DispatcherServlet說明spring

5、spring mvc 父子上下文的說明apache

6、springMVC-mvc.xml 配置文件片斷講解 
7、spring mvc 如何訪問到靜態的文件,如jpg,js,css編程

8、spring mvc 請求如何映射到具體的Action中的方法json

9、 spring mvc 中的攔截器:
10、 spring mvc 如何使用攔截器

11、 spring mvc 如何實現全局的異常處理

12、 spring mvc 如何把全局異常記錄到日誌中

十3、 如何給spring3 MVC中的Action作JUnit單元測試

十4、 spring mvc 轉發與重定向 (帶參數重定向)

十5、 spring mvc 處理ajax請求

十6、 spring mvc 關於寫幾個配置文件的說明 

十7、 spring mvc 如何取得Spring管理的bean

十8、 spring mvc 多視圖控制器

十9、 <mvc:annotation-driven /> 到底作了什麼工做 
二10、 本文中springMVC.xml配置文件是核心,這裏給一個下載地址

 

 

 

說明:本做者是文章的原創做者,轉載請註明出處:本文地址:http://elf8848.iteye.com/blog/875830

 

 

 

1、前言:

爲開發團隊選擇一款優秀的MVC框架是件難事兒,在衆多可行的方案中決擇須要很高的經驗和水平。你的一個決定會影響團隊將來的幾年。要考慮方面太多:

一、簡單易用,以提升開發效率。使小部分的精力在框架上,大部分的精力放在業務上。

二、性能優秀,這是一個最能吸引眼球的話題。

三、儘可能使用大衆的框架(避免使用小衆的、私有的框架),新招聘來的開發人員有一些這方面技術積累,減低人員流動再適應的影響。

 

若是你還在爲這件事件發愁,本文最適合你了。選擇Spring MVC吧。

 

Spring MVC是當前最優秀的MVC框架,自從Spring 2.5版本發佈後,因爲支持註解配置,易用性有了大幅度的提升。Spring 3.0更加完善,實現了對Struts 2的超越。如今愈來愈多的開發團隊選擇了Spring MVC。

 

Struts2也是很是優秀的MVC構架,優勢很是多好比良好的結構,攔截器的思想,豐富的功能。但這裏想說的是缺點,Struts2因爲採用了值棧、OGNL表達式、struts2標籤庫等,會致使應用的性能降低,應避免使用這些功能。而Struts2的多層攔截器、多實例action性能都很好。能夠參考我寫的一篇關於Spring MVC與Struts2與Servlet比較的文章《Struts二、SpringMVC、Servlet(Jsp)性能對比 測試》

 

Spring3 MVC的優勢:

一、Spring3 MVC使用簡單,學習成本低。學習難度小於Struts2,Struts2用不上的多餘功能太多。呵呵,固然這不是決定因素。

二、Spring3 MVC很容易就能夠寫出性能優秀的程序,Struts2要到處當心才能夠寫出性能優秀的程序(指MVC部分)

三、Spring3 MVC的靈活是你沒法想像的,Spring框架的擴展性有口皆碑,Spring3 MVC固然也不會落後,不會因使用了MVC框架而感到有任何的限制。

 

Struts2的衆多優勢:

一、老牌的知名框架,從Struts1起積累了大量用戶羣體。技術文檔豐富。

二、其它方面略...   (呵呵,是否是不公平?)

 

Spring的官方下載網址是:http://www.springsource.org/download    (本文使用是的Spring 3.0.5版本)

轉載請註明出處:原文地址:http://elf8848.iteye.com/blog/875830

 

2、核心類與接口:

 

先來了解一下,幾個重要的接口與類。如今不知道他們是幹什麼的不要緊,先混個臉熟,爲之後認識他們打個基礎。

 

DispatcherServlet   -- 前置控制器

 

HandlerMapping接口 -- 處理請求的映射

HandlerMapping接口的實現類:

SimpleUrlHandlerMapping  經過配置文件,把一個URL映射到Controller

DefaultAnnotationHandlerMapping  經過註解,把一個URL映射到Controller類上

 

HandlerAdapter接口 -- 處理請求的映射

AnnotationMethodHandlerAdapter類,經過註解,把一個URL映射到Controller類的方法上

 

Controller接口 -- 控制器

因爲咱們使用了@Controller註解,添加了@Controller註解註解的類就能夠擔任控制器(Action)的職責,

因此咱們並無用到這個接口。

 

 

 

HandlerInterceptor 接口--攔截器

無圖,咱們本身實現這個接口,來完成攔截的器的工做。

 

 

ViewResolver接口的實現類

UrlBasedViewResolver類 經過配置文件,把一個視圖名交給到一個View來處理

InternalResourceViewResolver類,比上面的類,加入了JSTL的支持

 

View接口

JstlView類

 

LocalResolver接口

 

HandlerExceptionResolver接口 --異常處理

SimpleMappingExceptionResolver實現類

 

 

ModelAndView類

無圖。

 

 

 

 

 

3、核心流程圖

 

本圖是我我的畫的,有不嚴謹的地方,你們對付看吧。總比沒的看強。

轉載請註明出處:本文地址:http://elf8848.iteye.com/blog/875830

 

 


4、DispatcherServlet說明

 

使用Spring MVC,配置DispatcherServlet是第一步。

DispatcherServlet是一個Servlet,因此能夠配置多個DispatcherServlet。

DispatcherServlet是前置控制器,配置在web.xml文件中的。攔截匹配的請求,Servlet攔截匹配規則要自已定義,把攔截下來的請求,依據某某規則分發到目標Controller(咱們寫的Action)來處理。

 

「某某規則」:是根據你使用了哪一個HandlerMapping接口的實現類的不一樣而不一樣。

 

先來看第一個例子:

Xml代碼   收藏代碼
  1. <web-app>  
  2.     <servlet>  
  3.         <servlet-name>example</servlet-name>  
  4.         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  5.         <load-on-startup>1</load-on-startup>  
  6.     </servlet>  
  7.     <servlet-mapping>  
  8.         <servlet-name>example</servlet-name>  
  9.         <url-pattern>*.form</url-pattern>  
  10.     </servlet-mapping>  
  11. </web-app>  

 <load-on-startup>1</load-on-startup>是啓動順序,讓這個Servlet隨Servletp容器一塊兒啓動。

 <url-pattern>*.form</url-pattern> 會攔截*.form結尾的請求。

 

 <servlet-name>example</servlet-name>這個Servlet的名字是example,能夠有多個DispatcherServlet,是經過名字來區分的。每個DispatcherServlet有本身的WebApplicationContext上下文對象。同時保存的ServletContext中和Request對象中,關於key,之後說明。

 

在DispatcherServlet的初始化過程當中,框架會在web應用的 WEB-INF文件夾下尋找名爲[servlet-name]-servlet.xml 的配置文件,生成文件中定義的bean。

 

 

第二個例子:

Xml代碼   收藏代碼
  1. <servlet>  
  2.     <servlet-name>springMVC</servlet-name>  
  3.     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  4.     <init-param>  
  5.         <param-name>contextConfigLocation</param-name>  
  6.         <param-value>classpath*:/springMVC.xml</param-value>  
  7.     </init-param>  
  8.     <load-on-startup>1</load-on-startup>  
  9. </servlet>  
  10. <servlet-mapping>  
  11.     <servlet-name>springMVC</servlet-name>  
  12.     <url-pattern>/</url-pattern>  
  13. </servlet-mapping>  

指明瞭配置文件的文件名,不使用默認配置文件名,而使用springMVC.xml配置文件。

其中<param-value>**.xml</param-value> 這裏可使用多種寫法
一、不寫,使用默認值:/WEB-INF/<servlet-name>-servlet.xml
二、<param-value>/WEB-INF/classes/springMVC.xml</param-value>
三、<param-value>classpath*:springMVC-mvc.xml</param-value>
四、多個值用逗號分隔

 


Servlet攔截匹配規則能夠自已定義,攔截哪一種URL合適? 
當映射爲@RequestMapping("/user/add")時,爲例:


一、攔截*.do、*.htm, 例如:/user/add.do

這是最傳統的方式,最簡單也最實用。不會致使靜態文件(jpg,js,css)被攔截。

 

二、攔截/,例如:/user/add

能夠實現如今很流行的REST風格。不少互聯網類型的應用很喜歡這種風格的URL。

弊端:會致使靜態文件(jpg,js,css)被攔截後不能正常顯示。想實現REST風格,事情就是麻煩一些。後面有解決辦法還算簡單。

 

三、攔截/*,這是一個錯誤的方式,請求能夠走到Action中,但轉到jsp時再次被攔截,不能訪問到jsp。

 

轉載請註明出處:本文地址:http://elf8848.iteye.com/blog/875830

 

5、父子上下文(WebApplicationContext)

 

若是你使用了listener監聽器來加載配置,通常在Struts+Spring+Hibernate的項目中都是使用listener監聽器的。以下

Java代碼   收藏代碼
  1. <listener>   
  2.   <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>   
  3. </listener>   

 

 

Spring會建立一個WebApplicationContext上下文,稱爲父上下文(父容器) ,保存在 ServletContext中,key是WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE的值。

可使用Spring提供的工具類取出上下文對象:WebApplicationContextUtils.getWebApplicationContext(ServletContext);

 

DispatcherServlet是一個Servlet,能夠同時配置多個,每一個 DispatcherServlet有一個本身的上下文對象(WebApplicationContext),稱爲子上下文(子容器),子上下文能夠訪問父上下文中的內容,但父上下文不能訪問子上下文中的內容。 它也保存在 ServletContext中,key是"org.springframework.web.servlet.FrameworkServlet.CONTEXT"+Servlet名稱。當一個Request對象產生時,會把這個子上下文對象(WebApplicationContext)保存在Request對象中,key是DispatcherServlet.class.getName() + ".CONTEXT"。

可使用工具類取出上下文對象:RequestContextUtils.getWebApplicationContext(request);

 

 

說明 :Spring 並無限制咱們,必須使用父子上下文。咱們能夠本身決定如何使用。

 

方案一,傳統型:

父上下文容器中保存數據源、服務層、DAO層、事務的Bean。

子上下文容器中保存Mvc相關的Action的Bean.

事務控制在服務層。

因爲父上下文容器不能訪問子上下文容器中內容,事務的Bean在父上下文容器中,沒法訪問子上下文容器中內容,就沒法對子上下文容器中Action進行AOP(事務)。

固然,作爲「傳統型」方案,也沒有必要這要作。

 

方案二,激進型:

Java世界的「面向接口編程」的思想是正確的,但在增刪改查爲主業務的系統裏,Dao層接口,Dao層實現類,Service層接口,Service層實現類,Action父類,Action。再加上衆多的O(vo\po\bo)和jsp頁面。寫一個小功能 七、8個類就寫出來了。 開發者說我就是想接點私活兒,和PHP,ASP搶搶飯碗,但我又是Java程序員。最好的結果是大項目能作好,小項目能作快。因此「激進型」方案就出現了-----沒有接口、沒有Service層、還能夠沒有衆多的O(vo\po\bo)。那沒有Service層事務控制在哪一層?只好上升的Action層。

本文不想說這是否是正確的思想,我想說的是Spring不會限制你這樣作。

因爲有了父子上下文,你將沒法實現這一目標。解決方案是只使用子上下文容器,不要父上下文容器 。因此數據源、服務層、DAO層、事務的Bean、Action的Bean都放在子上下文容器中。就能夠實現了,事務(註解事務)就正常工做了。這樣纔夠激進。

總結:不使用listener監聽器來加載spring的配置文件,只使用DispatcherServlet來加載spring的配置,不要父子上下文,只使用一個DispatcherServlet,事情就簡單了,什麼麻煩事兒也沒有了。

 

 

 

Java--大項目能作好--按傳統方式作,規規矩矩的作,好擴展,好維護。

Java--小項目能作快--按激進方式作,一週時間就能夠出一個版本,先上線接受市場(用戶)的反饋,再改進,再反饋,時間就是生命(成本)。

 

轉載請註明出處:原文地址:http://elf8848.iteye.com/blog/875830

 

6、springMVC-mvc.xml 配置文件片斷講解 (未使用默認配置文件名)

 

Xml代碼   收藏代碼
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans  
  3.     xmlns="http://www.springframework.org/schema/beans"  
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  5.     xmlns:tx="http://www.springframework.org/schema/tx"  
  6.     xmlns:context="http://www.springframework.org/schema/context"    
  7.     xmlns:mvc="http://www.springframework.org/schema/mvc"    
  8.     xsi:schemaLocation="http://www.springframework.org/schema/beans   
  9.     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd   
  10.     http://www.springframework.org/schema/tx   
  11.     http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  
  12.     http://www.springframework.org/schema/context  
  13.     http://www.springframework.org/schema/context/spring-context-3.0.xsd  
  14.     http://www.springframework.org/schema/mvc  
  15.     http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">  
  16.   
  17.   
  18.     <!-- 自動掃描的包名 -->  
  19.     <context:component-scan base-package="com.app,com.core,JUnit4" ></context:component-scan>  
  20.       
  21.     <!-- 默認的註解映射的支持 -->  
  22.     <mvc:annotation-driven />  
  23.       
  24.     <!-- 視圖解釋類 -->  
  25.     <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
  26.         <property name="prefix" value="/WEB-INF/jsp/"/>  
  27.         <property name="suffix" value=".jsp"/><!--可爲空,方便實現自已的依據擴展名來選擇視圖解釋類的邏輯  -->  
  28.         <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />  
  29.     </bean>  
  30.       
  31.     <!-- 攔截器 -->  
  32.     <mvc:interceptors>  
  33.         <bean class="com.core.mvc.MyInteceptor" />  
  34.     </mvc:interceptors>       
  35.       
  36.     <!-- 對靜態資源文件的訪問  方案一 (二選一) -->  
  37.     <mvc:default-servlet-handler/>  
  38.       
  39.     <!-- 對靜態資源文件的訪問  方案二 (二選一)-->  
  40.     <mvc:resources mapping="/images/**" location="/images/" cache-period="31556926"/>  
  41.     <mvc:resources mapping="/js/**" location="/js/" cache-period="31556926"/>  
  42.     <mvc:resources mapping="/css/**" location="/css/" cache-period="31556926"/>  
  43.   
  44. </beans>   

 

<context:component-scan/> 掃描指定的包中的類上的註解,經常使用的註解有:

@Controller 聲明Action組件
@Service    聲明Service組件    @Service("myMovieLister") 
@Repository 聲明Dao組件
@Component   泛指組件, 當很差歸類時. 
@RequestMapping("/menu")  請求映射
@Resource  用於注入,( j2ee提供的 ) 默認按名稱裝配,@Resource(name="beanName") 
@Autowired 用於注入,(srping提供的) 默認按類型裝配 
@Transactional( rollbackFor={Exception.class}) 事務管理
@ResponseBody
@Scope("prototype")   設定bean的做用域

 

<mvc:annotation-driven /> 是一種簡寫形式,徹底能夠手動配置替代這種簡寫形式,簡寫形式可讓初學都快速應用默認配置方案。<mvc:annotation-driven /> 會自動註冊DefaultAnnotationHandlerMapping與AnnotationMethodHandlerAdapter 兩個bean,是spring MVC爲@Controllers分發請求所必須的。
並提供了:數據綁定支持,@NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持,讀寫XML的支持(JAXB),讀寫JSON的支持(Jackson)。
後面,咱們處理響應ajax請求時,就使用到了對json的支持。
後面,對action寫JUnit單元測試時,要從spring IOC容器中取DefaultAnnotationHandlerMapping與AnnotationMethodHandlerAdapter 兩個bean,來完成測試,取的時候要知道是<mvc:annotation-driven />這一句註冊的這兩個bean。

如何替換 <mvc:annotation-driven />?他到底作了什麼工做,請看,最後面的 十九節 <mvc:annotation-driven /> 到底作了什麼工做。

 

<mvc:interceptors/> 是一種簡寫形式。經過看前面的大圖,知道,咱們能夠配置多個HandlerMapping。<mvc:interceptors/>會爲每個HandlerMapping,注入一個攔截器。其實咱們也能夠手動配置爲每一個HandlerMapping注入一個攔截器。

 

<mvc:default-servlet-handler/> 使用默認的Servlet來響應靜態文件。

 

<mvc:resources mapping="/images/**" location="/images/" cache-period="31556926"/> 匹配URL  /images/**  的URL被當作靜態資源,由Spring讀出到內存中再響應http。

轉載請註明出處:本文地址:http://elf8848.iteye.com/blog/875830

 
7、如何訪問到靜態的文件,如jpg,js,css?

 

 

如何你的DispatcherServlet攔截"*.do"這樣的有後綴的URL,就不存在訪問不到靜態資源的問題。

若是你的DispatcherServlet攔截"/",爲了實現REST風格,攔截了全部的請求,那麼同時對*.js,*.jpg等靜態文件的訪問也就被攔截了。

咱們要解決這個問題。

 

目的:能夠正常訪問靜態文件,不能夠找不到靜態文件報404。

 
方案一:激活Tomcat的defaultServlet來處理靜態文件

Xml代碼   收藏代碼
  1. <servlet-mapping>   
  2.     <servlet-name>default</servlet-name>  
  3.     <url-pattern>*.jpg</url-pattern>     
  4. </servlet-mapping>    
  5. <servlet-mapping>       
  6.     <servlet-name>default</servlet-name>    
  7.     <url-pattern>*.js</url-pattern>    
  8. </servlet-mapping>    
  9. <servlet-mapping>        
  10.     <servlet-name>default</servlet-name>       
  11.     <url-pattern>*.css</url-pattern>      
  12. </servlet-mapping>    
  13. 要配置多個,每種文件配置一個   

要寫在DispatcherServlet的前面, 讓 defaultServlet先攔截請求,這樣請求就不會進入Spring了,我想性能是最好的吧。

 

Tomcat, Jetty, JBoss, and GlassFish 自帶的默認Servlet的名字 -- "default"
Google App Engine 自帶的 默認Servlet的名字 -- "_ah_default"
Resin 自帶的 默認Servlet的名字 -- "resin-file"
WebLogic 自帶的 默認Servlet的名字  -- "FileServlet"
WebSphere  自帶的 默認Servlet的名字 -- "SimpleFileServlet" 

 

 


方案二: 在spring3.0.4之後版本提供了mvc:resources ,  使用方法:

Xml代碼   收藏代碼
  1. <!-- 對靜態資源文件的訪問 -->    
  2. <mvc:resources mapping="/images/**" location="/images/" />  

  
/images/**映射到ResourceHttpRequestHandler進行處理,location指定靜態資源的位置.能夠是web application根目錄下、jar包裏面,這樣能夠把靜態資源壓縮到jar包中。cache-period 可使得靜態資源進行web cache 
 
若是出現下面的錯誤,多是沒有配置<mvc:annotation-driven />的緣由。 
報錯WARNING: No mapping found for HTTP request with URI [/mvc/user/findUser/lisi/770] in DispatcherServlet with name 'springMVC'

 

使用<mvc:resources/>元素,把mapping的URI註冊到SimpleUrlHandlerMapping的urlMap中,
key爲mapping的URI pattern值,而value爲ResourceHttpRequestHandler,
這樣就巧妙的把對靜態資源的訪問由HandlerMapping轉到ResourceHttpRequestHandler處理並返回,因此就支持classpath目錄,jar包內靜態資源的訪問.
另外須要注意的一點是,不要對SimpleUrlHandlerMapping設置defaultHandler.由於對static uri的defaultHandler就是ResourceHttpRequestHandler,
不然沒法處理static resources request.

 

 

方案三 ,使用<mvc:default-servlet-handler/>

Xml代碼   收藏代碼
  1. <mvc:default-servlet-handler/>  

 

會把"/**" url,註冊到SimpleUrlHandlerMapping的urlMap中,把對靜態資源的訪問由HandlerMapping轉到org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler處理並返回.
DefaultServletHttpRequestHandler使用就是各個Servlet容器本身的默認Servlet.

 

 

補充說明:多個HandlerMapping的執行順序問題:

DefaultAnnotationHandlerMapping的order屬性值是:0

<mvc:resources/ >自動註冊的 SimpleUrlHandlerMapping的order屬性值是: 2147483646

 

<mvc:default-servlet-handler/>自動註冊 的SimpleUrlHandlerMapping 的order屬性值是: 2147483647

 

 

spring會先執行order值比較小的。當訪問一個a.jpg圖片文件時,先經過 DefaultAnnotationHandlerMapping 來找處理器,必定是找不到的,由於咱們沒有叫a.jpg的Action。而後再按order值升序找,因爲最後一個 SimpleUrlHandlerMapping 是匹配 "/**"的,因此必定會匹配上,就能夠響應圖片。

 

 

訪問一個圖片,還要走層層匹配。不知性能如何?

最後再說明一下,方案2、方案三 在訪問靜態資源時,若是有匹配的(近似)總攔截器,就會走攔截器。若是你在攔截中實現權限檢查,要注意過濾這些對靜態文件的請求。

如何你的DispatcherServlet攔截 *.do這樣的URL後綴,就不存上述問題了。仍是有後綴方便。

 

轉載請註明出處:原文地址:http://elf8848.iteye.com/blog/875830

 


8、請求如何映射到具體的Action中的方法?
方案一:基於xml配置映射,能夠利用SimpleUrlHandlerMapping、BeanNameUrlHandlerMapping進行Url映射和攔截請求。
配置方法略。
 
方案二:基於註解映射,可使用DefaultAnnotationHandlerMapping。

Xml代碼   收藏代碼
  1. <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">  </bean>   

 

但前面咱們配置了<mvc:annotation-driven />,他會自動註冊這個bean,就不需要咱們顯示的註冊這個bean了。  

如何替換 <mvc:annotation-driven />?他到底作了什麼工做,請看,最後面的 十九節 <mvc:annotation-driven /> 到底作了什麼工做。

 

 
以上均可以注入interceptors,實現權限控制等前置工做。
咱們使用第2種,基於註解來使用spring MVC

 

 

 並在action類上使用:
@Controller
@RequestMapping("/user")

轉載請註明出處:原文地址:http://elf8848.iteye.com/blog/875830 
 
 
9、Spring中的攔截器:
Spring爲咱們提供了:
org.springframework.web.servlet.HandlerInterceptor接口,

org.springframework.web.servlet.handler.HandlerInterceptorAdapter適配器,
實現這個接口或繼承此類,能夠很是方便的實現本身的攔截器。
 
有如下三個方法:
 
Action以前執行:
 public boolean preHandle(HttpServletRequest request,
   HttpServletResponse response, Object handler);
 
生成視圖以前執行
 public void postHandle(HttpServletRequest request,
   HttpServletResponse response, Object handler,
   ModelAndView modelAndView);
 
最後執行,可用於釋放資源
 public void afterCompletion(HttpServletRequest request,
   HttpServletResponse response, Object handler, Exception ex)
 
 
分別實現預處理、後處理(調用了Service並返回ModelAndView,但未進行頁面渲染)、返回處理(已經渲染了頁面) 
在preHandle中,能夠進行編碼、安全控制等處理; 
在postHandle中,有機會修改ModelAndView; 
在afterCompletion中,能夠根據ex是否爲null判斷是否發生了異常,進行日誌記錄。 
參數中的Object handler是下一個攔截器。
轉載請註明出處:原文地址:http://elf8848.iteye.com/blog/875830


10、如何使用攔截器?
自定義一個攔截器,要實現HandlerInterceptor接口:

Java代碼   收藏代碼
  1. public class MyInteceptor implements HandlerInterceptor {     
  2.     略。。。  
  3. }    

 

Spring MVC並無總的攔截器,不能對全部的請求進行先後攔截。
Spring MVC的攔截器,是屬於HandlerMapping級別的,能夠有多個HandlerMapping ,每一個HandlerMapping能夠有本身的攔截器。
當一個請求按Order值從小到大,順序執行HandlerMapping接口的實現類時,哪個先有返回,那就能夠結束了,後面的HandlerMapping就不走了,本道工序就完成了。就轉到下一道工序了。
攔截器會在何時執行呢? 一個請求交給一個HandlerMapping時,這個HandlerMapping先找有沒有處理器來處理這個請求,如何找到了,就執行攔截器,執行完攔截後,交給目標處理器。
若是沒有找處處理器,那麼這個攔截器就不會被執行。

 


在spring MVC的配置文件中配置有三種方法:


方案一,(近似)總攔截器,攔截全部url

Java代碼   收藏代碼
  1.    <mvc:interceptors>  
  2.     <bean class="com.app.mvc.MyInteceptor" />  
  3. </mvc:interceptors>  

爲何叫「近似」,前面說了,Spring沒有總的攔截器。

<mvc:interceptors/>會爲每個HandlerMapping,注入一個攔截器。總有一個HandlerMapping是能夠找處處理器的,最多也只找到一個處理器,因此這個攔截器總會被執行的。起到了總攔截器的做用。

若是是REST風格的URL,靜態資源也會被攔截。

 

 
方案二, (近似) 總攔截器, 攔截匹配的URL。

Xml代碼   收藏代碼
  1. <mvc:interceptors >    
  2.   <mvc:interceptor>    
  3.         <mvc:mapping path="/user/*" /> <!-- /user/*  -->    
  4.         <bean class="com.mvc.MyInteceptor"></bean>    
  5.     </mvc:interceptor>    
  6. </mvc:interceptors>    

就是比 方案一多了一個URL匹配。

若是是REST風格的URL,靜態資源也會被攔截。

 

 

 

方案三,HandlerMappint上的攔截器。

若是是REST風格的URL,靜態資源就不會被攔截。由於咱們精準的注入了攔截器。

Xml代碼   收藏代碼
  1. <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">       
  2.  <property name="interceptors">       
  3.      <list>       
  4.          <bean class="com.mvc.MyInteceptor"></bean>      
  5.      </list>       
  6.  </property>       
  7. </bean>   

  若是使用了<mvc:annotation-driven />, 它會自動註冊DefaultAnnotationHandlerMapping 與AnnotationMethodHandlerAdapter 這兩個bean,因此就沒有機會再給它注入interceptors屬性,就沒法指定攔截器。

固然咱們能夠經過人工配置上面的兩個Bean,不使用 <mvc:annotation-driven />,就能夠 給interceptors屬性 注入攔截器了。

 

其實我也不建議使用 <mvc:annotation-driven />,而建議手動寫詳細的配置文件,來替代 <mvc:annotation-driven />,這就控制力就強了。

如何替換 <mvc:annotation-driven />?他到底作了什麼工做,請看,最後面的 十九節 <mvc:annotation-driven /> 到底作了什麼工做。

轉載請註明出處:原文地址:http://elf8848.iteye.com/blog/875830

 

 

 

11、如何實現全局的異常處理?

在spring MVC的配置文件中:

Xml代碼   收藏代碼
  1. <!-- 總錯誤處理-->  
  2. <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">  
  3.     <property name="defaultErrorView">    
  4.         <value>/error/error</value>  
  5.     </property>  
  6.     <property name="defaultStatusCode">    
  7.         <value>500</value>  
  8.     </property>     
  9. <property name="warnLogCategory">    
  10.         <value>org.springframework.web.servlet.handler.SimpleMappingExceptionResolver</value>  
  11.     </property>     
  12. </bean>   

 

這裏主要的類是SimpleMappingExceptionResolver類,和他的父類AbstractHandlerExceptionResolver類。

具體能夠配置哪些屬性,我是經過查看源碼知道的。

你也能夠實現HandlerExceptionResolver接口,寫一個本身的異常處理程序。spring的擴展性是很好的。

 

 

經過SimpleMappingExceptionResolver咱們能夠將不一樣的異常映射到不一樣的jsp頁面(經過exceptionMappings屬性的配置)。

 

同時咱們也能夠爲全部的異常指定一個默認的異常提示頁面(經過defaultErrorView屬性的配置),若是所拋出的異常在exceptionMappings中沒有對應的映射,則Spring將用此默認配置顯示異常信息。

注意這裏配置的異常顯示界面均僅包括主文件名,至於文件路徑和後綴已經在viewResolver中指定。如/error/error表示/error/error.jsp

 

 

顯示錯誤的jsp頁面:

Html代碼   收藏代碼
  1. <%@ page language="java" contentType="text/html; charset=GBK"  
  2.     pageEncoding="GBK"%>  
  3. <%@ page import="java.lang.Exception"%>  
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  5. <html>  
  6. <head>  
  7. <meta http-equiv="Content-Type" content="text/html; charset=GBK">  
  8. <title>錯誤頁面</title>  
  9. </head>  
  10. <body>  
  11. <h1>出錯了</h1>  
  12. <%  
  13. Exception e = (Exception)request.getAttribute("exception");  
  14. out.print(e.getMessage());  
  15. %>  
  16. </body>  
  17. </html>  

其中一句:request.getAttribute("exception"),key是exception,也是在SimpleMappingExceptionResolver類默認指定的,是可能經過配置文件修改這個值的,你們能夠去看源碼。

 

 

 

12、如何把全局異常記錄到日誌中?

在前的配置中,其中有一個屬性warnLogCategory,值是「SimpleMappingExceptionResolver類的全限定名」。我是在SimpleMappingExceptionResolver類父類AbstractHandlerExceptionResolver類中找到這個屬性的。查看源碼後得知:若是warnLogCategory不爲空,spring就會使用apache的org.apache.commons.logging.Log日誌工具,記錄這個異常,級別是warn。

值:「org.springframework.web.servlet.handler.SimpleMappingExceptionResolver」,是「SimpleMappingExceptionResolver類的全限定名」。這個值不是隨便寫的。  由於我在log4j的配置文件中還要加入log4j.logger.org.springframework.web.servlet.handler.SimpleMappingExceptionResolver=WARN,保證這個級別是warn的日誌必定會被記錄,即便log4j的根日誌級別是ERROR。

轉載請註明出處:原文地址:http://elf8848.iteye.com/blog/875830

 

 

 

 十3、如何給spring3 MVC中的Action作JUnit單元測試?

 使用了spring3 MVC後,給action作單元測試變得很方便,我之前歷來不給action寫單元測試的,如今能夠根據狀況寫一些了。

 不用給每一個Action都寫單元測試吧,本身把握吧。

 

 JUnitActionBase類是全部JUnit的測試類的父類

 

Java代碼   收藏代碼
  1. package test;  
  2. import javax.servlet.http.HttpServletRequest;  
  3. import javax.servlet.http.HttpServletResponse;  
  4. import org.junit.BeforeClass;  
  5. import org.springframework.mock.web.MockServletContext;  
  6. import org.springframework.web.context.WebApplicationContext;  
  7. import org.springframework.web.context.support.XmlWebApplicationContext;  
  8. import org.springframework.web.servlet.HandlerAdapter;  
  9. import org.springframework.web.servlet.HandlerExecutionChain;  
  10. import org.springframework.web.servlet.HandlerMapping;  
  11. import org.springframework.web.servlet.ModelAndView;  
  12. import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter;  
  13. import org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping;  
  14. /**  
  15. * 說明: JUnit測試action時使用的基類 
  16. *  
  17. * @author  趙磊 
  18. * @version 建立時間:2011-2-2 下午10:27:03   
  19. */   
  20. public class JUnitActionBase {  
  21.     private static HandlerMapping handlerMapping;  
  22.     private static HandlerAdapter handlerAdapter;  
  23.     /** 
  24.      * 讀取spring3 MVC配置文件 
  25.      */  
  26.     @BeforeClass  
  27.  public static void setUp() {  
  28.         if (handlerMapping == null) {  
  29.             String[] configs = { "file:src/springConfig/springMVC.xml" };  
  30.             XmlWebApplicationContext context = new XmlWebApplicationContext();  
  31.             context.setConfigLocations(configs);  
  32.             MockServletContext msc = new MockServletContext();  
  33.             context.setServletContext(msc);         context.refresh();  
  34.             msc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, context);  
  35.             handlerMapping = (HandlerMapping) context  
  36.                     .getBean(DefaultAnnotationHandlerMapping.class);  
  37.             handlerAdapter = (HandlerAdapter) context.getBean(context.getBeanNamesForType(AnnotationMethodHandlerAdapter.class)[0]);     
  38.         }  
  39.     }  
  40.   
  41.     /** 
  42.      * 執行request對象請求的action 
  43.      *  
  44.      * @param request 
  45.      * @param response 
  46.      * @return 
  47.      * @throws Exception 
  48.      */  
  49.     public ModelAndView excuteAction(HttpServletRequest request, HttpServletResponse response)  
  50.  throws Exception {  
  51.         HandlerExecutionChain chain = handlerMapping.getHandler(request);  
  52.         final ModelAndView model = handlerAdapter.handle(request, response,  
  53.                 chain.getHandler());  
  54.         return model;  
  55.     }  
  56. }  

 

 

 

這是個JUnit測試類,咱們能夠new Request對象,來參與測試,太方便了。給request指定訪問的URL,就能夠請求目標Action了。

 

Java代碼   收藏代碼
  1. package test.com.app.user;  
  2. import org.junit.Assert;  
  3. import org.junit.Test;  
  4. import org.springframework.mock.web.MockHttpServletRequest;  
  5. import org.springframework.mock.web.MockHttpServletResponse;  
  6. import org.springframework.web.servlet.ModelAndView;  
  7.   
  8. import test.JUnitActionBase;  
  9.   
  10. /**  
  11. * 說明: 測試OrderAction的例子 
  12. *  
  13. * @author  趙磊  
  14. * @version 建立時間:2011-2-2 下午10:26:55   
  15. */   
  16.   
  17. public class TestOrderAction extends JUnitActionBase {  
  18.     @Test  
  19.     public void testAdd() throws Exception {  
  20.     MockHttpServletRequest request = new MockHttpServletRequest();  
  21.         MockHttpServletResponse response = new MockHttpServletResponse();  
  22.         request.setServletPath("/order/add");  
  23.         request.addParameter("id", "1002");  
  24.         request.addParameter("date", "2010-12-30");  
  25.         request.setMethod("POST");  
  26.         // 執行URI對應的action  
  27.         final ModelAndView mav = this.excuteAction(request, response);  
  28.         // Assert logic  
  29.         Assert.assertEquals("order/add", mav.getViewName());  
  30.         String msg=(String)request.getAttribute("msg");  
  31.         System.out.println(msg);  
  32.     }  
  33. }  

 須要說明一下 :因爲當前最想版本的Spring(Test) 3.0.5還不支持@ContextConfiguration的註解式context file注入,因此還須要寫個setUp處理下,不然相似於Tiles的加載過程會有錯誤,由於沒有ServletContext。3.1的版本應該有更好的解決方案,

參見: https://jira.springsource.org/browse/SPR-5243 

參考 :http://www.iteye.com/topic/828513

 

 

 

 

 十4、轉發與重定向

能夠經過redirect/forward:url方式轉到另外一個Action進行連續的處理。

能夠經過redirect:url 防止表單重複提交 。

寫法以下:

return "forward:/order/add";

return "redirect:/index.jsp";

轉載請註明出處:原文地址:http://elf8848.iteye.com/blog/875830

 

 

帶參數重定向--RedirectAttributes

用戶保存或修改後,爲了防止用戶刷新瀏覽器(F5)致使表單重複提交,通常在保存或修改操做以後會redirect到一個結果頁面(不是forward),同時攜帶參數,如操做成功的提示信息。由於是Redirect,Request裏的attribute不會傳遞過去。Spring在3.1才提供了這個能力--RedirectAttributes。 反覆按F5,操做成功的提示信息也不會再次出來(總共只出現一次),效果很理想。

 

Java代碼   收藏代碼
  1. public String save(@ModelAttribute("group") Group group, RedirectAttributes redirectAttributes) {  
  2.     accountManager.saveGroup(group);  
  3.     redirectAttributes.addFlashAttribute("message", "操做成功");  
  4.     return "redirect:/account/group/";  
  5. }  
 

 

 

 十5、處理ajax請求

 

一、引入下面兩個jar包,我用的是1.7.2,好像1.4.2版本以上均可以,下載地址:http://wiki.fasterxml.com/JacksonDownload

jackson-core-asl-1.7.2.jar 

jackson-mapper-asl-1.7.2.jar

 

二、spring的配置文件中要有這一行,才能使用到spring內置支持的json轉換。若是你手工把POJO轉成json就能夠不需要使用spring內置支持的json轉換。

<mvc:annotation-driven />

 

三、使用@ResponseBody註解

Java代碼   收藏代碼
  1. /** 
  2.  * ajax測試 
  3. * http://127.0.0.1/mvc/order/ajax 
  4.  */  
  5.   
  6. @RequestMapping("/ajax")  
  7. @ResponseBody  
  8. public Object ajax(HttpServletRequest request){  
  9.     List<String> list=new ArrayList<String>();  
  10.     list.add("電視");  
  11. nbsp;       list.add("洗衣機");  
  12.     list.add("冰箱");  
  13.     list.add("電腦");  
  14.     list.add("汽車");  
  15.     list.add("空調");  
  16.     list.add("自行車");  
  17.     list.add("飲水機");  
  18.     list.add("熱水器");  
  19.     return list;  
  20. }  

 

轉載請註明出處:原文地址:http://elf8848.iteye.com/blog/875830

 

 

 

十6、關於寫幾個配置文件的說明 

我看到有的人把配置文件寫兩份:
一個是原有的applicationContext.xml,這個文件從spring2.0-2.5時一直在使用。
別一個是新加的spring MVC的配置文件。
其實這兩個文件是能夠寫成一個文件的,springMVC相關的配置,數據源,事務相關配置能夠都寫再一個配置文件中。
本例子中只使用了一個spring配置文件叫「springMVC.xml」。
就不要再多配置一個applicationContext.xml文件了。
web.xml文件中也不要再配置org.springframework.web.context.ContextLoaderListener的listener了。
寫兩個配置文件通常就會致使掃描兩次,必定要精確控制掃描的包名,作到不重複掃描。

寫兩個配置文件還出現事務很差使的現象,是當把@Transactional寫有Action層時出現的。

是由於父子上下文的緣由,請參看前的 第五節 父子上下文,裏面有說明 。緣由是父上下文不能訪問子上下文。

 

 

 

十7、如何取得Spring管理的bean (請用第3種方法)
一、servlet方式加載時,
【web.xml】

Xml代碼   收藏代碼
  1. <servlet>  
  2. <servlet-name>springMVC</servlet-name>  
  3. <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  4. <init-param>  
  5. <param-name>contextConfigLocation</param-name>  
  6. <param-value>classpath*:/springMVC.xml</param-value>  
  7. </init-param>  
  8. <load-on-startup>1</load-on-startup>  
  9. </servlet>  

 spring容器放在ServletContext中的key是org.springframework.web.servlet.FrameworkServlet.CONTEXT.springMVC
注意後面的springMVC,是你的servlet-name配置的值,注意適時修改。

Java代碼   收藏代碼
  1. ServletContext sc=略  
  2. WebApplicationContext attr = (WebApplicationContext)sc.getAttribute("org.springframework.web.servlet.FrameworkServlet.CONTEXT.springMVC");  
 

二、listener方式加載時:
【web.xml】

Xml代碼   收藏代碼
  1. <context-param>  
  2.   <param-name>contextConfigLocation</param-name>  
  3.   <param-value>/WEB-INF/applicationContext</param-value>  
  4. </context-param>  
  5.   
  6. <listener>  
  7.   <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
  8. </listener>  

 【jsp/servlet】能夠這樣取得

Java代碼   收藏代碼
  1. ServletContext context = getServletContext();  
  2. WebApplicationContext applicationContext  = WebApplicationContextUtils .getWebApplicationContext(context);   
 

三、通用的方法來了,神器啊,前的  一、2兩種方法並不通用,能夠拋棄了。
在配置文件中加入:

Xml代碼   收藏代碼
  1. <!-- 用於持有ApplicationContext,可使用SpringContextHolder.getBean('xxxx')的靜態方法獲得spring bean對象 -->  
  2. <bean class="com.xxxxx.SpringContextHolder" lazy-init="false" />  
 
Java代碼   收藏代碼
  1. import org.springframework.context.ApplicationContext;  
  2. import org.springframework.context.ApplicationContextAware;  
  3. /** 
  4.  * 以靜態變量保存Spring ApplicationContext, 可在任何代碼任何地方任什麼時候候中取出ApplicaitonContext. 
  5.  *  
  6.  */  
  7. public class SpringContextHolder implements ApplicationContextAware {  
  8. private static ApplicationContext applicationContext;  
  9.   
  10. /** 
  11. * 實現ApplicationContextAware接口的context注入函數, 將其存入靜態變量. 
  12. */  
  13. public void setApplicationContext(ApplicationContext applicationContext) {  
  14. SpringContextHolder.applicationContext = applicationContext; // NOSONAR  
  15. }  
  16.   
  17. /** 
  18. * 取得存儲在靜態變量中的ApplicationContext. 
  19. */  
  20. public static ApplicationContext getApplicationContext() {  
  21. checkApplicationContext();  
  22. return applicationContext;  
  23. }  
  24.   
  25. /** 
  26. * 從靜態變量ApplicationContext中取得Bean, 自動轉型爲所賦值對象的類型. 
  27. */  
  28. @SuppressWarnings("unchecked")  
  29. public static <T> T getBean(String name) {  
  30. checkApplicationContext();  
  31. return (T) applicationContext.getBean(name);  
  32. }  
  33.   
  34. /** 
  35. * 從靜態變量ApplicationContext中取得Bean, 自動轉型爲所賦值對象的類型. 
  36. */  
  37. @SuppressWarnings("unchecked")  
  38. public static <T> T getBean(Class<T> clazz) {  
  39. checkApplicationContext();  
  40. return (T) applicationContext.getBeansOfType(clazz);  
  41. }  
  42.   
  43. /** 
  44. * 清除applicationContext靜態變量. 
  45. */  
  46. public static void cleanApplicationContext() {  
  47. applicationContext = null;  
  48. }  
  49.   
  50. private static void checkApplicationContext() {  
  51. if (applicationContext == null) {  
  52. throw new IllegalStateException("applicaitonContext未注入,請在applicationContext.xml中定義SpringContextHolder");  
  53. }  
  54. }  
  55. }  

  轉載請註明出處:原文地址:http://elf8848.iteye.com/blog/875830

 

 

十8、多視圖控制器

 

當有jsp,flt (模板)等多種頁面生成展現方式時,spring默認使用的是「視圖解析器鏈」。 真是一個鏈,因此性能很差,spring會在「視圖解析器鏈」中順序的查找,直到找到對應的 「視圖解析器」 。jsp視圖解析器必定要寫在最後面,由於一旦調用jsp,就向瀏覽器發出數據了,Spring就沒有機會再嘗試下一個了。

因此本身寫一個"多視圖解析器",依靠擴展名來區分,可一次準確的選中一個 視圖解析器,提升性能(會有多少提升呢?沒測試過).

 

下面的例子支持jsp,flt (模板)兩種頁面生成展現方式,你中以本身添加,支持更多。

 

Xml代碼   收藏代碼
  1.    <!-- 多視圖處理器 -->  
  2.    <bean class="com.xxx.core.web.MixedViewResolver">  
  3.     <property name="resolvers">  
  4.         <map>  
  5.             <entry key="jsp">  
  6.                 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
  7.                     <property name="prefix" value="/WEB-INF/jsp/"/>  
  8.                     <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>  
  9.                 </bean>  
  10.             </entry>  
  11.             <entry key="ftl">  
  12.                 <bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">  
  13.                     <property name="cache" value="true"/>  
  14.                     <property name="contentType" value="text/html;charset=UTF-8"></property>  
  15.                     <!-- 宏命令的支持  -->    
  16.                     <property name="exposeSpringMacroHelpers" value="true"/>  
  17.                     <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"/>  
  18.                     <property name="requestContextAttribute" value="rc"></property>  
  19.                 </bean>  
  20.             </entry>  
  21.         </map>  
  22.     </property>  
  23. </bean>  
  24.   
  25. <!-- freemarker config -->  
  26.    <bean id="freeMarkerConfigurer" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">   
  27.        <property name="templateLoaderPath" value="/WEB-INF/ftl/" />   
  28.        <property name="freemarkerSettings">   
  29.            <props>   
  30.                <prop key="template_update_delay">5</prop>   
  31.                <prop key="default_encoding">UTF-8</prop>   
  32.                <prop key="locale">zh_CN</prop>   
  33.            </props>   
  34.        </property>   
  35.    </bean>   
  

 

Java代碼   收藏代碼
  1. import java.util.Locale;  
  2. import java.util.Map;  
  3. import org.springframework.web.servlet.View;  
  4. import org.springframework.web.servlet.ViewResolver;  
  5.   
  6. /**  
  7. * 說明: 多視圖處理器 
  8. *  
  9. * @author  趙磊  
  10. * @version 建立時間:2011-8-19 上午09:41:09   
  11. */   
  12. public class MixedViewResolver implements ViewResolver{  
  13.     private Map<String,ViewResolver> resolvers;  
  14.   
  15.     public void setResolvers(Map<String, ViewResolver> resolvers) {  
  16.         this.resolvers = resolvers;  
  17.     }  
  18.       
  19.     public View resolveViewName(String viewName,Locale locale) throws Exception{  
  20.         int n=viewName.lastIndexOf(".");  
  21.         if(n!=-1){  
  22.             //取出擴展名  
  23.             String suffix=viewName.substring(n+1);  
  24.             //取出對應的ViewResolver  
  25.             ViewResolver resolver=resolvers.get(suffix);  
  26.             if(resolver==null){  
  27.                 throw new RuntimeException("No ViewResolver for "+suffix);  
  28.             }  
  29.             return  resolver.resolveViewName(viewName, locale);  
  30.         }else{  
  31.             ViewResolver resolver=resolvers.get("jsp");  
  32.             return  resolver.resolveViewName(viewName, locale);  
  33.         }  
  34.     }  
  35. }  

  轉載請註明出處:原文地址:http://elf8848.iteye.com/blog/875830

 

 

十9、 <mvc:annotation-driven /> 到底作了什麼工做

 

 

一句 <mvc:annotation-driven />實際作了如下工做:(不包括添加本身定義的攔截器)

咱們瞭解這些以後,對Spring3 MVC的控制力就更強大了,想改哪就改哪裏。

Xml代碼   收藏代碼
  1.    <!-- 註解請求映射  -->  
  2.    <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">          
  3.     <property name="interceptors">  
  4.         <list>    
  5.             <ref bean="logNDCInteceptor"/>   <!-- 日誌攔截器,這是你自定義的攔截器 -->  
  6.             <ref bean="myRequestHelperInteceptor"/>   <!-- RequestHelper攔截器,這是你自定義的攔截器-->   
  7.             <ref bean="myPermissionsInteceptor"/>  <!-- 權限攔截器,這是你自定義的攔截器-->   
  8.             <ref bean="myUserInfoInteceptor"/>  <!-- 用戶信息攔截器,這是你自定義的攔截器-->   
  9.         </list>          
  10.     </property>          
  11. </bean>     
  12. <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">  
  13.     <property name="messageConverters">    
  14.         <list>    
  15.             <ref bean="byteArray_hmc" />    
  16.             <ref bean="string_hmc" />    
  17.             <ref bean="resource_hmc" />    
  18.             <ref bean="source_hmc" />    
  19.             <ref bean="xmlAwareForm_hmc" />    
  20.             <ref bean="jaxb2RootElement_hmc" />    
  21.             <ref bean="jackson_hmc" />    
  22.         </list>    
  23.     </property>    
  24. </bean>    
  25. <bean id="byteArray_hmc" class="org.springframework.http.converter.ByteArrayHttpMessageConverter" /><!-- 處理.. -->  
  26. <bean id="string_hmc" class="org.springframework.http.converter.StringHttpMessageConverter" /><!-- 處理.. -->  
  27. <bean id="resource_hmc" class="org.springframework.http.converter.ResourceHttpMessageConverter" /><!-- 處理.. -->  
  28. <bean id="source_hmc" class="org.springframework.http.converter.xml.SourceHttpMessageConverter" /><!-- 處理.. -->  
  29. <bean id="xmlAwareForm_hmc" class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter" /><!-- 處理.. -->  
  30. <bean id="jaxb2RootElement_hmc" class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter" /><!-- 處理.. -->  
  31. <bean id="jackson_hmc" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" /><!-- 處理json-->  

  轉載請註明出處:原文地址:http://elf8848.iteye.com/blog/875830

 

 

 

二10、 本文中springMVC.xml配置文件是核心,這裏給一個下載地址

 

要在http://www.iteye.com/網站有註冊賬號才能下載(這不能怪我)

 

Spring_MVC_教程_快速入門_深刻分析V1.1.pdf

 

SpringMVC核心配置文件示例.rar

相關文章
相關標籤/搜索