日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring MVC 3 深入总结

發布時間:2025/4/14 javascript 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring MVC 3 深入总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

一、前言:

大家好,Spring3 MVC是非常優秀的MVC框架,由其是在3.0版本號公布后,如今有越來越多的團隊選擇了Spring3 MVC了。Spring3 MVC結構簡單,應了那句話簡單就是美,并且他強大不失靈活,性能也非常優秀。

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

?

Struts2也是比較優秀的MVC構架,長處非常多比方良好的結構。但這里想說的是缺點,Struts2因為採用了值棧、OGNL表達式、struts2標簽庫等,會導致應用的性能下降。Struts2的多層攔截器、多實例action性能都非常好。能夠參考我寫的一篇關于Spring MVC與Struts2與Servlet比較的文章?http://elf8848.iteye.com/admin/blogs/698217

?

Spring3 MVC的長處:

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

2、Spring3 MVC非常easy就能夠寫出性能優秀的程序,Struts2要處處小心才干夠寫出性能優秀的程序(指MVC部分)

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

?

Struts2的眾多長處:略...?? (呵呵,是不是不公平?)

?

眾多文章開篇時總要吹些牛,吸引一下讀者的眼球,把讀者的胃口調起來,這樣大家才有興趣接著往后看。本文也沒能例外。只是保證你看了之后不會懊悔定有收獲。

?

?

二、核心類與接口:

?

先來了解一下,幾個重要的接口與類。如今不知道他們是干什么的沒關系,先混個臉熟,為以后認識他們打個基礎。

?

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類

無圖。

?

?

?

?

?

三、核心流程圖

?

本圖是我個人畫的,有不嚴謹的地方,大家對付看吧。總比沒的看強。

?

?

?


四、DispatcherServlet說明

?

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

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

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

?

“某某規則”:是依據你使用了哪個HandlerMapping接口的實現類的不同而不同。

?

先來看第一個樣例:

Xml代碼?
  • <web-app>??
  • ????<servlet>??
  • ????????<servlet-name>example</servlet-name>??
  • ????????<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>??
  • ????????<load-on-startup>1</load-on-startup>??
  • ????</servlet>??
  • ????<servlet-mapping>??
  • ????????<servlet-name>example</servlet-name>??
  • ????????<url-pattern>*.form</url-pattern>??
  • ????</servlet-mapping>??
  • </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代碼?
  • <servlet>??
  • ????<servlet-name>springMVC</servlet-name>??
  • ????<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>??
  • ????<init-param>??
  • ????????<param-name>contextConfigLocation</param-name>??
  • ????????<param-value>classpath*:/springMVC.xml</param-value>??
  • ????</init-param>??
  • ????<load-on-startup>1</load-on-startup>??
  • </servlet>??
  • <servlet-mapping>??
  • ????<servlet-name>springMVC</servlet-name>??
  • ????<url-pattern>/</url-pattern>??
  • </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攔截匹配規則能夠自已定義,Servlet攔截哪種URL合適??

    當映射為@RequestMapping("/user/add")時:
    1、攔截*.do,比如:/user/add.do,弊端:全部的url都要以.do結尾。不會影響訪問靜態文件。
    2、攔截/app/*,比如:/app/user/add,弊端:請求的url都要包括/app,@RequestMapping("/user/add")中不需要包括/app。
    3、攔截/,比如:/user/add,弊端:對jpg,js,css靜態文件的訪問也被攔截不能正常顯示。后面有解決的方法。
    4、攔截/*,能夠走到Action中,但轉發到jsp時再次被攔截,不能訪問到jsp。

    ?

    ?

    五、雙親上下文的說明

    ?

    假設你使用了listener監聽器來載入配置,一般在Struts+Spring+Hibernate的項目中都是使用listener監聽器的。例如以下

    Java代碼?
  • <listener>???
  • ??<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>???
  • </listener>???
  • Spring會創建一個全局的WebApplicationContext上下文,稱為根上下文?,保存在?ServletContext中,key是WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE屬性的值。能夠使用工具類取出上下文: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中的 ApplicationContext實例能夠被限制在不同的作用域(scope)中。
    在web MVC框架中,每一個 DispatcherServlet有它自己的WebApplicationContext ,這個context繼承了根 WebApplicationContext 的全部bean定義。
    這些繼承的bean也能夠在每一個serlvet自己的所屬的域中被覆蓋(override),覆蓋后的bean 能夠被設置上僅僅有這個servlet實例自己使用的屬性。

    ?

    總結:不使用listener監聽器來載入spring的配置,改用DispatcherServlet來載入spring的配置,不要雙親上下文,僅僅使用一個DispatcherServlet,事情就簡單了,什么麻煩事兒也沒有了。

    ?

    ?

    六、springMVC-mvc.xml 配置文件片段解說?(未使用默認配置文件名稱)

    ?

    Xml代碼?
  • ???<!--?自己主動掃描的包名?-->??
  • ???<context:component-scan?base-package="com.app,com.core,JUnit4"?></context:component-scan>??
  • ?????
  • ???<!--?默認的注解映射的支持?-->??
  • ???<mvc:annotation-driven?/>??
  • ?????
  • ???<!--?視圖解釋類?-->??
  • ???<bean?class="org.springframework.web.servlet.view.InternalResourceViewResolver">??
  • ????<property?name="prefix"?value="/WEB-INF/jsp/"/>??
  • ????<property?name="suffix"?value=".jsp"/><!--可為空,方便實現自已的根據擴展名來選擇視圖解釋類的邏輯??-->??
  • ????<property?name="viewClass"?value="org.springframework.web.servlet.view.JstlView"?/>??
  • ???</bean>??
  • ?????
  • <!--?攔截器?-->??
  • ???<mvc:interceptors>??
  • ????<bean?class="com.core.mvc.MyInteceptor"?/>??
  • </mvc:interceptors>???????
  • ??
  • ????<!--?對靜態資源文件的訪問??方案一?(二選一)?-->??
  • ????<mvc:default-servlet-handler/>??
  • ??????
  • ????<!--?對靜態資源文件的訪問??方案二?(二選一)-->??
  • <mvc:resources?mapping="/images/**"?location="/images/"?cache-period="31556926"/>??
  • <mvc:resources?mapping="/js/**"?location="/js/"?cache-period="31556926"/>??
  • <mvc:resources?mapping="/css/**"?location="/css/"?cache-period="31556926"/>??
  • ?

    <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: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。

    ?

    ?
    七、怎樣訪問到靜態的文件,如jpg,js,css?


    怎樣你的DispatcherServlet攔截 *.do這種URL,就不存在訪問不到靜態資源的問題。假設你的DispatcherServlet攔截“/”,攔截了全部的請求,同一時候對*.js,*.jpg的訪問也就被攔截了。

    ?

    目的:能夠正常訪問靜態文件,不要找不到靜態文件報404。
    ?
    方案一:激活Tomcat的defaultServlet來處理靜態文件

    Xml代碼?
  • <servlet-mapping>???
  • ????<servlet-name>default</servlet-name>??
  • ????<url-pattern>*.jpg</url-pattern>?????
  • </servlet-mapping>????
  • <servlet-mapping>???????
  • ????<servlet-name>default</servlet-name>????
  • ????<url-pattern>*.js</url-pattern>????
  • </servlet-mapping>????
  • <servlet-mapping>????????
  • ????<servlet-name>default</servlet-name>???????
  • ????<url-pattern>*.css</url-pattern>??????
  • </servlet-mapping>????
  • 要配置多個,每種文件配置一個???
  • 要寫在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?
    mvc:resources 的用法:

    Xml代碼?
  • <!--?對靜態資源文件的訪問?-->????
  • <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代碼?
  • <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?是匹配?"/**"的,所以一定會匹配上,再響應圖片。

    ?

    訪問一個圖片,還要走層層匹配。真不知性能怎樣?改天做一下壓力測試,與Apache比一比。

    ?

    最后再說明一下,怎樣你的DispatcherServlet攔截 *.do這種URL,就不存上述問題了。

    ?

    ?


    八、請求怎樣映射到詳細的Action中的方法?
    方案一:基于xml配置映射,能夠利用SimpleUrlHandlerMapping、BeanNameUrlHandlerMapping進行Url映射和攔截請求。
    配置方法略。
    ?
    方案二:基于注解映射,能夠使用DefaultAnnotationHandlerMapping。

    Xml代碼?
  • <bean?class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">??</bean>???
  • ?

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

    ?

    ?
    以上都能夠注入interceptors,實現權限控制等前置工作。
    我們使用第2種,基于注解來使用spring MVC

    ?

    ?

    ?并在action類上使用:
    @Controller
    @RequestMapping("/user")
    ?
    ?
    ?
    九、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是下一個攔截器。
    ?


    十、怎樣使用攔截器?
    自己定義一個攔截器,要實現HandlerInterceptor接口:

    Java代碼?
  • public?class?MyInteceptor?implements?HandlerInterceptor?{?????
  • ????略。。。??
  • }????
  • ?

    Spring MVC并沒有總的攔截器,不能對全部的請求進行前后攔截。
    Spring MVC的攔截器,是屬于HandlerMapping級別的,能夠有多個HandlerMapping ,每一個HandlerMapping能夠有自己的攔截器。
    當一個請求按Order值從小到大,順序運行HandlerMapping接口的實現類時,哪一個先有返回,那就能夠結束了,后面的HandlerMapping就不走了,本道工序就完畢了。就轉到下一道工序了。
    攔截器會在什么時候運行呢? 一個請求交給一個HandlerMapping時,這個HandlerMapping先找有沒有處理器來處理這個請求,怎樣找到了,就運行攔截器,運行完攔截后,交給目標處理器。
    假設沒有找到處理器,那么這個攔截器就不會被運行。

    ?


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


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

    Java代碼?
  • ???<mvc:interceptors>??
  • ????<bean?class="com.app.mvc.MyInteceptor"?/>??
  • </mvc:interceptors>??
  • 為什么叫“近似”,前面說了,Spring沒有總的攔截器。

    <mvc:interceptors/>會為每一 個HandlerMapping,注入一個攔截器。總有一個HandlerMapping是能夠找到處理器的,最多也僅僅找到一個處理器,所以這個攔截器總會被運行的。起到了總攔截器的作用。

    ?

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

    Xml代碼?
  • <mvc:interceptors?>????
  • ??<mvc:interceptor>????
  • ????????<mvc:mapping?path="/user/*"?/>?<!--?/user/*??-->????
  • ????????<bean?class="com.mvc.MyInteceptor"></bean>????
  • ????</mvc:interceptor>????
  • </mvc:interceptors>????
  • 就是比?方案一多了一個URL匹配。

    ?

    ?

    ?

    方案三,HandlerMappint上的攔截器

    Xml代碼?
  • <bean?class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">???????
  • ?<property?name="interceptors">???????
  • ?????<list>???????
  • ?????????<bean?class="com.mvc.MyInteceptor"></bean>??????
  • ?????</list>???????
  • ?</property>???????
  • </bean>???
  • ??假設使用了<mvc:annotation-driven />,?它會自己主動注冊DefaultAnnotationHandlerMapping 與AnnotationMethodHandlerAdapter 這兩個bean,所以就沒有機會再給它注入interceptors屬性,就無法指定攔截器。

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

    ?

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

    ?

    ?

    ?

    ?

    十一、怎樣實現全局的異常處理?

    在spring MVC的配置文件里:

    Xml代碼?
  • <!--?總錯誤處理-->??
  • <bean?id="exceptionResolver"?class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">??
  • ????<property?name="defaultErrorView">????
  • ????????<value>/error/error</value>??
  • ????</property>??
  • ????<property?name="defaultStatusCode">????
  • ????????<value>500</value>??
  • ????</property>?????
  • <property?name="warnLogCategory">????
  • ????????<value>org.springframework.web.servlet.handler.SimpleMappingExceptionResolver</value>??
  • ????</property>?????
  • </bean>???
  • ?

    這里基本的類是SimpleMappingExceptionResolver類,和他的父類AbstractHandlerExceptionResolver類。

    詳細能夠配置哪些屬性,我是通過查看源代碼知道的。

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

    ?

    ?

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

    ?

    同一時候我們也能夠為全部的異常指定一個默認的異常提示頁面(通過defaultErrorView屬性的配置),假設所拋出的異常在exceptionMappings中沒有相應的映射,則Spring將用此默認配置顯示異常信息。

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

    ?

    ?

    顯示錯誤的jsp頁面:

    Html代碼?
  • <%@?page?language="java"?contentType="text/html;?charset=GBK"??
  • ????pageEncoding="GBK"%>??
  • <%@?page?import="java.lang.Exception"%>??
  • <!DOCTYPE?html?PUBLIC?"-//W3C//DTD?HTML?4.01?Transitional//EN"?"http://www.w3.org/TR/html4/loose.dtd">??
  • <html>??
  • <head>??
  • <meta?http-equiv="Content-Type"?content="text/html;?charset=GBK">??
  • <title>錯誤頁面</title>??
  • </head>??
  • <body>??
  • <h1>出錯了</h1>??
  • <%??
  • Exception?e?=?(Exception)request.getAttribute("exception");??
  • out.print(e.getMessage());??
  • %>??
  • </body>??
  • </html>??
  • 當中一句:request.getAttribute("exception"),key是exception,也是在SimpleMappingExceptionResolver類默認指定的,是可能通過配置文件改動這個值的,大家能夠去看源代碼。

    ?

    ?參考文章:

    http://www.blogjava.net/wuxufeng8080/articles/191150.html

    http://fangjunai.blog.163.com/blog/static/1124970520108102013839/

    ?

    ?

    ?

    十二、怎樣把全局異常記錄到日志中?

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

    ?

    ?

    ?

    ?

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

    ?使用了spring3 MVC后,給action做單元測試也非常方便,我曾經從來不給action寫單元測試的,再在不同了,方便了,所以一定要寫。

    ?

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

    ?

    Java代碼?
  • package?test;??
  • import?javax.servlet.http.HttpServletRequest;??
  • import?javax.servlet.http.HttpServletResponse;??
  • import?org.junit.BeforeClass;??
  • import?org.springframework.mock.web.MockServletContext;??
  • import?org.springframework.web.context.WebApplicationContext;??
  • import?org.springframework.web.context.support.XmlWebApplicationContext;??
  • import?org.springframework.web.servlet.HandlerAdapter;??
  • import?org.springframework.web.servlet.HandlerExecutionChain;??
  • import?org.springframework.web.servlet.HandlerMapping;??
  • import?org.springframework.web.servlet.ModelAndView;??
  • import?org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter;??
  • import?org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping;??
  • /**??
  • *?說明:?JUnit測試action時使用的基類?
  • *??
  • *?@author??趙磊?
  • *?@version?創建時間:2011-2-2?下午10:27:03???
  • */???
  • public?class?JUnitActionBase?{??
  • ????private?static?HandlerMapping?handlerMapping;??
  • ????private?static?HandlerAdapter?handlerAdapter;??
  • ????/**?
  • ?????*?讀取spring3?MVC配置文件?
  • ?????*/??
  • ????@BeforeClass??
  • ?public?static?void?setUp()?{??
  • ????????if?(handlerMapping?==?null)?{??
  • ????????????String[]?configs?=?{?"file:src/springConfig/springMVC.xml"?};??
  • ????????????XmlWebApplicationContext?context?=?new?XmlWebApplicationContext();??
  • ????????????context.setConfigLocations(configs);??
  • ????????????MockServletContext?msc?=?new?MockServletContext();??
  • ????????????context.setServletContext(msc);?????????context.refresh();??
  • ????????????msc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,?context);??
  • ????????????handlerMapping?=?(HandlerMapping)?context??
  • ????????????????????.getBean(DefaultAnnotationHandlerMapping.class);??
  • ????????????handlerAdapter?=?(HandlerAdapter)?context.getBean(context.getBeanNamesForType(AnnotationMethodHandlerAdapter.class)[0]);?????
  • ????????}??
  • ????}??
  • ??
  • ????/**?
  • ?????*?運行request對象請求的action?
  • ?????*??
  • ?????*?@param?request?
  • ?????*?@param?response?
  • ?????*?@return?
  • ?????*?@throws?Exception?
  • ?????*/??
  • ????public?ModelAndView?excuteAction(HttpServletRequest?request,?HttpServletResponse?response)??
  • ?throws?Exception?{??
  • ????????HandlerExecutionChain?chain?=?handlerMapping.getHandler(request);??
  • ????????final?ModelAndView?model?=?handlerAdapter.handle(request,?response,??
  • ????????????????chain.getHandler());??
  • ????????return?model;??
  • ????}??
  • }??
  • ?

    ?

    ?

    ?

    ?

    ?

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

    ?

    Java代碼?
  • package?test.com.app.user;??
  • import?org.junit.Assert;??
  • import?org.junit.Test;??
  • import?org.springframework.mock.web.MockHttpServletRequest;??
  • import?org.springframework.mock.web.MockHttpServletResponse;??
  • import?org.springframework.web.servlet.ModelAndView;??
  • ??
  • import?test.JUnitActionBase;??
  • ??
  • /**??
  • *?說明:?測試OrderAction的樣例?
  • *??
  • *?@author??趙磊??
  • *?@version?創建時間:2011-2-2?下午10:26:55???
  • */???
  • ??
  • public?class?TestOrderAction?extends?JUnitActionBase?{??
  • ????@Test??
  • ????public?void?testAdd()?throws?Exception?{??
  • ????MockHttpServletRequest?request?=?new?MockHttpServletRequest();??
  • ????????MockHttpServletResponse?response?=?new?MockHttpServletResponse();??
  • ????????request.setRequestURI("/order/add");??
  • ????????request.addParameter("id",?"1002");??
  • ????????request.addParameter("date",?"2010-12-30");??
  • ????????request.setMethod("POST");??
  • ????????//?運行URI相應的action??
  • ????????final?ModelAndView?mav?=?this.excuteAction(request,?response);??
  • ????????//?Assert?logic??
  • ????????Assert.assertEquals("order/add",?mav.getViewName());??
  • ????????String?msg=(String)request.getAttribute("msg");??
  • ????????System.out.println(msg);??
  • ????}??
  • }??
  • ?須要說明一下?:由于當前最想版本號的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

    ?

    ?

    ?

    ?

    ?十四、轉發與重定向

    能夠通過redirect/forward:url方式轉到還有一個Action進行連續的處理。

    能夠通過redirect:url 防止表單反復提交?

    寫法例如以下:

    return "forward:/order/add";

    return "redirect:/index.jsp";

    ?

    ?

    ?

    ?

    ?十五、處理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內置支持的json轉換。假設你手工把POJO轉成json就能夠不需要使用spring內置支持的json轉換。

    <mvc:annotation-driven />

    ?

    3、使用@ResponseBody注解

    Java代碼?
  • /**?
  • ?*?ajax測試?
  • *?http://127.0.0.1/mvc/order/ajax?
  • ?*/??
  • ??
  • @RequestMapping("/ajax")??
  • @ResponseBody??
  • public?Object?ajax(HttpServletRequest?request){??
  • ????List<String>?list=new?ArrayList<String>();??
  • ????list.add("電視");??
  • nbsp;???????list.add("洗衣機");??
  • ????list.add("冰箱");??
  • ????list.add("電腦");??
  • ????list.add("汽車");??
  • ????list.add("空調");??
  • ????list.add("自行車");??
  • ????list.add("飲水機");??
  • ????list.add("熱水器");??
  • ????return?list;??
  • }??
  • ?

    轉載于:https://www.cnblogs.com/gcczhongduan/p/4313474.html

    總結

    以上是生活随笔為你收集整理的Spring MVC 3 深入总结的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。