<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 495,comments - 227,trackbacks - 0

    資源下載:

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

    SpringMVC核心配置文件示例.rar

     

     

    作者:趙磊

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

     

    目錄

    一、前言
    二、spring mvc 核心類與接口
    三、spring mvc 核心流程圖

    四、spring mvc DispatcherServlet說明

    五、spring mvc 父子上下文的說明

    六、springMVC-mvc.xml 配置文件片段講解
    七、spring mvc 如何訪問到靜態(tài)的文件,如jpg,js,css

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

    九、 spring mvc 中的攔截器:
    十、
    spring mvc 如何使用攔截器

    十一、 spring mvc 如何實現(xiàn)全局的異常處理

    十二、 spring mvc 如何把全局異常記錄到日志中

    十三、 如何給spring3 MVC中的Action做JUnit單元測試

    十四、 spring mvc 轉(zhuǎn)發(fā)與重定向 (帶參數(shù)重定向)

    十五、 spring mvc 處理ajax請求

    十六、 spring mvc 關(guān)于寫幾個配置文件的說明 

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

    十八、 spring mvc 多視圖控制器

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

     

     

     

    說明:本作者是文章的原創(chuàng)作者,轉(zhuǎn)載請注明出處:本文地址:http://elf8848.iteye.com/blog/875830

     

     

     

    一、前言:

    為開發(fā)團隊選擇一款優(yōu)秀的MVC框架是件難事兒,在眾多可行的方案中決擇需要很高的經(jīng)驗和水平。你的一個決定會影響團隊未來的幾年。要考慮方面太多:

    1、簡單易用,以提高開發(fā)效率。使小部分的精力在框架上,大部分的精力放在業(yè)務(wù)上。

    2、性能優(yōu)秀,這是一個最能吸引眼球的話題。

    3、盡量使用大眾的框架(避免使用小眾的、私有的框架),新招聘來的開發(fā)人員有一些這方面技術(shù)積累,減低人員流動再適應的影響。

     

    如果你還在為這件事件發(fā)愁,本文最適合你了。選擇Spring MVC吧。

     

    Spring MVC是當前最優(yōu)秀的MVC框架,自從Spring 2.5版本發(fā)布后,由于支持注解配置,易用性有了大幅度的提高。Spring 3.0更加完善,實現(xiàn)了對Struts 2的超越。現(xiàn)在越來越多的開發(fā)團隊選擇了Spring MVC。

     

    Struts2也是非常優(yōu)秀的MVC構(gòu)架,優(yōu)點非常多比如良好的結(jié)構(gòu),攔截器的思想,豐富的功能。但這里想說的是缺點,Struts2由于采用了值 棧、OGNL表達式、struts2標簽庫等,會導致應用的性能下降,應避免使用這些功能。而Struts2的多層攔截器、多實例action性能都很 好??梢詤⒖嘉覍懙囊黄P(guān)于Spring MVC與Struts2與Servlet比較的文章《Struts2、SpringMVC、Servlet(Jsp)性能對比 測試》

     

    Spring3 MVC的優(yōu)點:

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

    2、Spring3 MVC很容易就可以寫出性能優(yōu)秀的程序,Struts2要處處小心才可以寫出性能優(yōu)秀的程序(指MVC部分)

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

     

    Struts2的眾多優(yōu)點:

    1、老牌的知名框架,從Struts1起積累了大量用戶群體。技術(shù)文檔豐富。

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

     

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

    轉(zhuǎn)載請注明出處:原文地址:http://elf8848.iteye.com/blog/875830

     

    二、核心類與接口:

     

    先來了解一下,幾個重要的接口與類?,F(xiàn)在不知道他們是干什么的沒關(guān)系,先混個臉熟,為以后認識他們打個基礎(chǔ)。

     

    DispatcherServlet   -- 前置控制器

     

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

    HandlerMapping接口的實現(xiàn)類:

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

    DefaultAnnotationHandlerMapping  通過注解,把一個URL映射到Controller類上

     

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

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

     

    Controller接口 -- 控制器

    由于我們使用了@Controller注解,添加了@Controller注解注解的類就可以擔任控制器(Action)的職責,

    所以我們并沒有用到這個接口。

     

     

     

    HandlerInterceptor 接口--攔截器

    無圖,我們自己實現(xiàn)這個接口,來完成攔截的器的工作。

     

     

    ViewResolver接口的實現(xiàn)類

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

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

     

    View接口

    JstlView類

     

    LocalResolver接口

     

    HandlerExceptionResolver接口 --異常處理

    SimpleMappingExceptionResolver實現(xiàn)類

     

     

    ModelAndView類

    無圖。

     

     

     

     

     

    三、核心流程圖

     

    本圖是我個人畫的,有不嚴謹?shù)牡胤?,大家對付看吧??偙葲]的看強。

    轉(zhuǎn)載請注明出處:本文地址:http://elf8848.iteye.com/blog/875830

     

     


    四、DispatcherServlet說明

     

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

    DispatcherServlet是一個Servlet,所以可以配置多個DispatcherServlet。

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

     

    “某某規(guī)則”:是根據(jù)你使用了哪個HandlerMapping接口的實現(xiàn)類的不同而不同。

     

    先來看第一個例子:

    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結(jié)尾的請求。

     

     <servlet-name>example</servlet-name>這個Servlet的名字是 example,可以有多個DispatcherServlet,是通過名字來區(qū)分的。每一個DispatcherServlet有自己的 WebApplicationContext上下文對象。同時保存的ServletContext中和Request對象中,關(guān)于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> 這里可以使用多種寫法
    1、不寫,使用默認值:/WEB-INF/<servlet-name>-servlet.xml
    2、<param-value>/WEB-INF/classes/springMVC.xml</param-value>
    3、<param-value>classpath*:springMVC-mvc.xml</param-value>
    4、多個值用逗號分隔

     


    Servlet攔截匹配規(guī)則可以自已定義,攔截哪種URL合適?
    當映射為@RequestMapping("/user/add")時,為例:


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

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

     

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

    可以實現(xiàn)現(xiàn)在很流行的REST風格。很多互聯(lián)網(wǎng)類型的應用很喜歡這種風格的URL。

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

     

    3、攔截/*,這是一個錯誤的方式,請求可以走到Action中,但轉(zhuǎn)到j(luò)sp時再次被攔截,不能訪問到j(luò)sp。

     

    轉(zhuǎn)載請注明出處:本文地址:http://elf8848.iteye.com/blog/875830

     

    五、父子上下文(WebApplicationContext)

     

    如果你使用了listener監(jiān)聽器來加載配置,一般在Struts+Spring+Hibernate的項目中都是使用listener監(jiān)聽器的。如下

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

     

     

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

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

     

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

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

     

     

    說明 :Spring 并沒有限制我們,必須使用父子上下文。我們可以自己決定如何使用。

     

    方案一,傳統(tǒng)型:

    父上下文容器中保存數(shù)據(jù)源、服務(wù)層、DAO層、事務(wù)的Bean。

    子上下文容器中保存Mvc相關(guān)的Action的Bean.

    事務(wù)控制在服務(wù)層。

    由于父上下文容器不能訪問子上下文容器中內(nèi)容,事務(wù)的Bean在父上下文容器中,無法訪問子上下文容器中內(nèi)容,就無法對子上下文容器中Action進行AOP(事務(wù))。

    當然,做為“傳統(tǒng)型”方案,也沒有必要這要做。

     

    方案二,激進型:

    Java世界的“面向接口編程”的思想是正確的,但在增刪改查為主業(yè)務(wù)的系統(tǒng)里,Dao層接口,Dao層實現(xiàn)類,Service層接 口,Service層實現(xiàn)類,Action父類,Action。再加上眾多的O(vo\po\bo)和jsp頁面。寫一個小功能 7、8個類就寫出來了。 開發(fā)者說我就是想接點私活兒,和PHP,ASP搶搶飯碗,但我又是Java程序員。最好的結(jié)果是大項目能做好,小項目能做快。所以“激進型”方案就出現(xiàn)了 -----沒有接口、沒有Service層、還可以沒有眾多的O(vo\po\bo)。那沒有Service層事務(wù)控制在哪一層?只好上升的Action 層。

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

    由于有了父子上下文,你將無法實現(xiàn)這一目標。解決方案是只使用子上下文容器,不要父上下文容器 。所以數(shù)據(jù)源、服務(wù)層、DAO層、事務(wù)的Bean、Action的Bean都放在子上下文容器中。就可以實現(xiàn)了,事務(wù)(注解事務(wù))就正常工作了。這樣才夠激進。

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

     

     

     

    Java--大項目能做好--按傳統(tǒng)方式做,規(guī)規(guī)矩矩的做,好擴展,好維護。

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

     

    轉(zhuǎn)載請注明出處:原文地址:http://elf8848.iteye.com/blog/875830

     

    六、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"/><!--可為空,方便實現(xiàn)自已的依據(jù)擴展名來選擇視圖解釋類的邏輯  -->  
    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.     <!-- 對靜態(tài)資源文件的訪問  方案一 (二選一) -->  
    37.     <mvc:default-servlet-handler/>  
    38.       
    39.     <!-- 對靜態(tài)資源文件的訪問  方案二 (二選一)-->  
    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}) 事務(wù)管理
    @ResponseBody
    @Scope("prototype")   設(shè)定bean的作用域

     

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

    如何替換 <mvc:annotation-driven />?他到底做了什么工作,請看,最后面的 十九節(jié) <mvc:annotation-driven /> 到底做了什么工作。

     

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

     

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

     

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

    轉(zhuǎn)載請注明出處:本文地址:http://elf8848.iteye.com/blog/875830

     
    七、如何訪問到靜態(tài)的文件,如jpg,js,css?

     

     

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

    如果你的DispatcherServlet攔截"/",為了實現(xiàn)REST風格,攔截了所有的請求,那么同時對*.js,*.jpg等靜態(tài)文件的訪問也就被攔截了。

    我們要解決這個問題。

     

    目的:可以正常訪問靜態(tài)文件,不可以找不到靜態(tài)文件報404。

     
    方案一:激活Tomcat的defaultServlet來處理靜態(tài)文件

    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. <!-- 對靜態(tài)資源文件的訪問 -->    
    2. <mvc:resources mapping="/images/**" location="/images/" />  

      
    /images/**映射到 ResourceHttpRequestHandler進行處理,location指定靜態(tài)資源的位置.可以是web application根目錄下、jar包里面,這樣可以把靜態(tài)資源壓縮到j(luò)ar包中。cache-period 可以使得靜態(tài)資源進行web cache 
     
    如果出現(xiàn)下面的錯誤,可能是沒有配置<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,
    這樣就巧妙的把對靜態(tài)資源的訪問由HandlerMapping轉(zhuǎn)到ResourceHttpRequestHandler處理并返回,所以就支持classpath目錄,jar包內(nèi)靜態(tài)資源的訪問.
    另外需要注意的一點是,不要對SimpleUrlHandlerMapping設(shè)置defaultHandler.因為對static uri的defaultHandler就是ResourceHttpRequestHandler,
    否則無法處理static resources request.

     

     

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

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

    會把"/**" url,注冊到SimpleUrlHandlerMapping的urlMap中,把對靜態(tài)資源的訪問由HandlerMapping轉(zhuǎn)到 org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler 處理并返回.
    DefaultServletHttpRequestHandler使用就是各個Servlet容器自己的默認Servlet.

     

     

    補充說明:多個HandlerMapping的執(zhí)行順序問題:

    DefaultAnnotationHandlerMapping的order屬性值是:0

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

     

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

     

     

    spring會先執(zhí)行order值比較小的。當訪問一個a.jpg圖片文件時,先通過 DefaultAnnotationHandlerMapping 來找處理器,一定是找不到的,因為我們沒有叫a.jpg的Action。然后再按order值升序找,由于最后一個 SimpleUrlHandlerMapping 是匹配 "/**"的,所以一定會匹配上,就可以響應圖片。

     

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

    最后再說明一下,方案二、方案三 在訪問靜態(tài)資源時,如果有匹配的(近似)總攔截器,就會走攔截器。如果你在攔截中實現(xiàn)權(quán)限檢查,要注意過濾這些對靜態(tài)文件的請求。

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

     

    轉(zhuǎn)載請注明出處:原文地址:http://elf8848.iteye.com/blog/875830

     


    八、請求如何映射到具體的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 />?他到底做了什么工作,請看,最后面的 十九節(jié) <mvc:annotation-driven /> 到底做了什么工作。


     
    以上都可以注入interceptors,實現(xiàn)權(quán)限控制等前置工作。
    我們使用第2種,基于注解來使用spring MVC

     

     

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

    轉(zhuǎn)載請注明出處:原文地址:http://elf8848.iteye.com/blog/875830
     
     
    九、Spring中的攔截器:
    Spring為我們提供了:
    org.springframework.web.servlet.HandlerInterceptor接口,

    org.springframework.web.servlet.handler.HandlerInterceptorAdapter適配器,
    實現(xiàn)這個接口或繼承此類,可以非常方便的實現(xiàn)自己的攔截器。
     
    有以下三個方法:
     
    Action之前執(zhí)行:
     public boolean preHandle(HttpServletRequest request,
       HttpServletResponse response, Object handler);
     
    生成視圖之前執(zhí)行
     public void postHandle(HttpServletRequest request,
       HttpServletResponse response, Object handler,
       ModelAndView modelAndView);
     
    最后執(zhí)行,可用于釋放資源
     public void afterCompletion(HttpServletRequest request,
       HttpServletResponse response, Object handler, Exception ex)
     
     
    分別實現(xiàn)預處理、后處理(調(diào)用了Service并返回ModelAndView,但未進行頁面渲染)、返回處理(已經(jīng)渲染了頁面)
    在preHandle中,可以進行編碼、安全控制等處理;
    在postHandle中,有機會修改ModelAndView;
    在afterCompletion中,可以根據(jù)ex是否為null判斷是否發(fā)生了異常,進行日志記錄。
    參數(shù)中的Object handler是下一個攔截器。
    轉(zhuǎn)載請注明出處:原文地址:http://elf8848.iteye.com/blog/875830


    十、如何使用攔截器?
    自定義一個攔截器,要實現(xiàn)HandlerInterceptor接口:

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

     

    Spring MVC并沒有總的攔截器,不能對所有的請求進行前后攔截。
    Spring MVC的攔截器,是屬于HandlerMapping級別的,可以有多個HandlerMapping ,每個HandlerMapping可以有自己的攔截器。
    當一個請求按Order值從小到大,順序執(zhí)行HandlerMapping接口的實現(xiàn)類時,哪一個先有返回,那就可以結(jié)束了,后面的HandlerMapping就不走了,本道工序就完成了。就轉(zhuǎn)到下一道工序了。
    攔截器會在什么時候執(zhí)行呢? 一個請求交給一個HandlerMapping時,這個HandlerMapping先找有沒有處理器來處理這個請求,如何找到了,就執(zhí)行攔截器,執(zhí)行完攔截后,交給目標處理器。
    如果沒有找到處理器,那么這個攔截器就不會被執(zhí)行。

     


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


    方案一,(近似)總攔截器,攔截所有url

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

    為什么叫“近似”,前面說了,Spring沒有總的攔截器。

    <mvc:interceptors/>會為每一個HandlerMapping,注入一個攔截器??傆幸粋€HandlerMapping是可以找到處理器的,最多也只找到一個處理器,所以這個攔截器總會被執(zhí)行的。起到了總攔截器的作用。

    如果是REST風格的URL,靜態(tài)資源也會被攔截。

     

     
    方案二, (近似) 總攔截器, 攔截匹配的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,靜態(tài)資源也會被攔截。

     

     

     

    方案三,HandlerMappint上的攔截器。

    如果是REST風格的URL,靜態(tài)資源就不會被攔截。因為我們精準的注入了攔截器。

    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 />?他到底做了什么工作,請看,最后面的 十九節(jié) <mvc:annotation-driven /> 到底做了什么工作。

    轉(zhuǎn)載請注明出處:原文地址:http://elf8848.iteye.com/blog/875830

     

     

     

    十一、如何實現(xiàn)全局的異常處理?

    在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類。

    具體可以配置哪些屬性,我是通過查看源碼知道的。

    你也可以實現(xiàn)HandlerExceptionResolver接口,寫一個自己的異常處理程序。spring的擴展性是很好的。

     

     

    通過SimpleMappingExceptionResolver我們可以將不同的異常映射到不同的jsp頁面(通過exceptionMappings屬性的配置)。

     

    同時我們也可以為所有的異常指定一個默認的異常提示頁面(通過defaultErrorView屬性的配置),如果所拋出的異常在exceptionMappings中沒有對應的映射,則Spring將用此默認配置顯示異常信息。

    注意這里配置的異常顯示界面均僅包括主文件名,至于文件路徑和后綴已經(jīng)在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類默認指定的,是可能通過配置文件修改這個值的,大家可以去看源碼。

     

     

     

    十二、如何把全局異常記錄到日志中?

    在前的配置中,其中有一個屬性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。

    轉(zhuǎn)載請注明出處:原文地址:http://elf8848.iteye.com/blog/875830

     

     

     

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

     使用了spring3 MVC后,給action做單元測試變得很方便,我以前從來不給action寫單元測試的,現(xiàn)在可以根據(jù)情況寫一些了。

     不用給每個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 創(chuàng)建時間: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.      * 執(zhí)行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 創(chuàng)建時間: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.         // 執(zhí)行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

     

     

     

     

     十四、轉(zhuǎn)發(fā)與重定向

    可以通過redirect/forward:url方式轉(zhuǎn)到另一個Action進行連續(xù)的處理。

    可以通過redirect:url 防止表單重復提交 。

    寫法如下:

    return "forward:/order/add";

    return "redirect:/index.jsp";

    轉(zhuǎn)載請注明出處:原文地址:http://elf8848.iteye.com/blog/875830

     

     

    帶參數(shù)重定向--RedirectAttributes

    用戶保存或修改后,為了防止用戶刷新瀏覽器(F5)導致表單重復提交,一般在保存或修改操作之后會redirect到一個結(jié)果頁面(不是 forward),同時攜帶參數(shù),如操作成功的提示信息。因為是Redirect,Request里的attribute不會傳遞過去。Spring在 3.1才提供了這個能力--RedirectAttributes。 反復按F5,操作成功的提示信息也不會再次出來(總共只出現(xiàn)一次),效果很理想。

     

    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. }  
     

     

     

     十五、處理ajax請求

     

    1、引入下面兩個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

     

    2、spring的配置文件中要有這一行,才能使用到spring內(nèi)置支持的json轉(zhuǎn)換。如果你手工把POJO轉(zhuǎn)成json就可以不須要使用spring內(nèi)置支持的json轉(zhuǎn)換。

    <mvc:annotation-driven />

     

    3、使用@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("空調(diào)");  
    16.     list.add("自行車");  
    17.     list.add("飲水機");  
    18.     list.add("熱水器");  
    19.     return list;  
    20. }  

     

    轉(zhuǎn)載請注明出處:原文地址:http://elf8848.iteye.com/blog/875830

     

     

     

    十六、關(guān)于寫幾個配置文件的說明

    我看到有的人把配置文件寫兩份:
    一個是原有的applicationContext.xml,這個文件從spring2.0-2.5時一直在使用。
    別一個是新加的spring MVC的配置文件。
    其實這兩個文件是可以寫成一個文件的,springMVC相關(guān)的配置,數(shù)據(jù)源,事務(wù)相關(guān)配置可以都寫再一個配置文件中。
    本例子中只使用了一個spring配置文件叫“springMVC.xml”。
    就不要再多配置一個applicationContext.xml文件了。
    web.xml文件中也不要再配置org.springframework.web.context.ContextLoaderListener的listener了。
    寫兩個配置文件一般就會導致掃描兩次,一定要精確控制掃描的包名,做到不重復掃描。

    寫兩個配置文件還出現(xiàn)事務(wù)不好使的現(xiàn)象,是當把@Transactional寫有Action層時出現(xiàn)的。

    是因為父子上下文的原因,請參看前的 第五節(jié) 父子上下文,里面有說明 。原因是父上下文不能訪問子上下文。

     

     

     

    十七、如何取得Spring管理的bean (請用第3種方法)
    1、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");  
     

    2、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);   
     

    3、通用的方法來了,神器啊,前的  1、2兩種方法并不通用,可以拋棄了。
    在配置文件中加入:

    Xml代碼  收藏代碼
    1. <!-- 用于持有ApplicationContext,可以使用SpringContextHolder.getBean('xxxx')的靜態(tài)方法得到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.  * 以靜態(tài)變量保存Spring ApplicationContext, 可在任何代碼任何地方任何時候中取出ApplicaitonContext. 
    5.  *  
    6.  */  
    7. public class SpringContextHolder implements ApplicationContextAware {  
    8. private static ApplicationContext applicationContext;  
    9.   
    10. /** 
    11. * 實現(xiàn)ApplicationContextAware接口的context注入函數(shù), 將其存入靜態(tài)變量. 
    12. */  
    13. public void setApplicationContext(ApplicationContext applicationContext) {  
    14. SpringContextHolder.applicationContext = applicationContext; // NOSONAR  
    15. }  
    16.   
    17. /** 
    18. * 取得存儲在靜態(tài)變量中的ApplicationContext. 
    19. */  
    20. public static ApplicationContext getApplicationContext() {  
    21. checkApplicationContext();  
    22. return applicationContext;  
    23. }  
    24.   
    25. /** 
    26. * 從靜態(tài)變量ApplicationContext中取得Bean, 自動轉(zhuǎn)型為所賦值對象的類型. 
    27. */  
    28. @SuppressWarnings("unchecked")  
    29. public static <T> T getBean(String name) {  
    30. checkApplicationContext();  
    31. return (T) applicationContext.getBean(name);  
    32. }  
    33.   
    34. /** 
    35. * 從靜態(tài)變量ApplicationContext中取得Bean, 自動轉(zhuǎn)型為所賦值對象的類型. 
    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靜態(tài)變量. 
    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. }  

      轉(zhuǎn)載請注明出處:原文地址:http://elf8848.iteye.com/blog/875830

     

     

    十八、多視圖控制器

     

    當有jsp,flt (模板)等多種頁面生成展示方式時,spring默認使用的是“視圖解析器鏈”。 真是一個鏈,所以性能不好,spring會在“視圖解析器鏈”中順序的查找,直到找到對應的 “視圖解析器” 。jsp視圖解析器一定要寫在最后面,因為一旦調(diào)用jsp,就向瀏覽器發(fā)出數(shù)據(jù)了,Spring就沒有機會再嘗試下一個了。

    所以自己寫一個"多視圖解析器",依靠擴展名來區(qū)分,可一次準確的選中一個 視圖解析器,提高性能(會有多少提高呢?沒測試過).

     

    下面的例子支持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 創(chuàng)建時間: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. }  

      轉(zhuǎn)載請注明出處:原文地址:http://elf8848.iteye.com/blog/875830

     

     

    十九、 <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"/>  <!-- 權(quán)限攔截器,這是你自定義的攔截器-->   
    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-->  

      轉(zhuǎn)載請注明出處:原文地址:http://elf8848.iteye.com/blog/875830

     

     

     

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

     

    要在http://www.iteye.com/網(wǎng)站有注冊帳號才能下載(這不能怪我)

     

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

     

    SpringMVC核心配置文件示例.rar

     

     

     

     

     

     

     

     

     

     

    posted on 2014-10-31 10:33 SIMONE 閱讀(437) 評論(0)  編輯  收藏 所屬分類: JSP
    主站蜘蛛池模板: 你懂的免费在线观看| 亚洲欧洲另类春色校园网站| 亚洲成色在线综合网站| 亚洲人成网站影音先锋播放| 97se亚洲综合在线| 亚洲欧洲专线一区| 免费人人潮人人爽一区二区| 中文字幕乱码系列免费| 欧洲亚洲国产精华液| www成人免费视频| 亚洲综合国产成人丁香五月激情| 鲁啊鲁在线视频免费播放| 中文字幕手机在线免费看电影| 蜜桃视频在线观看免费视频网站WWW| 18禁止观看免费私人影院| 国产又大又长又粗又硬的免费视频| 亚洲色偷偷综合亚洲AV伊人| 久久久久久a亚洲欧洲AV| 亚洲一区精品视频在线| 特a级免费高清黄色片| 亚洲成人免费在线| 国产网站免费观看| 成年人免费网站在线观看| 亚洲 综合 国产 欧洲 丝袜| 嫩草视频在线免费观看| 久久青青草原亚洲av无码| 亚洲婷婷在线视频| 人人公开免费超级碰碰碰视频| 51在线视频免费观看视频| 免费人妻无码不卡中文字幕18禁| 亚洲国产高清视频| 在线观看亚洲免费视频| 久久成人无码国产免费播放| 免费毛片在线视频| 亚洲人成亚洲精品| 亚洲欧美在线x视频| 人妻无码一区二区三区免费| a国产成人免费视频| 二个人看的www免费视频| 中文字幕无码免费久久99| 中文字幕不卡亚洲|