springmvc相關配置和用法

目錄以下:css

1、spring mvc 核心類與接口java

2、spring mvc 核心流程圖程序員

3、spring mvc DispatcherServlet說明web

4、spring mvc 父子上下文的說明ajax

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

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

8、 spring mvc 中的攔截器
9、 spring mvc 如何使用攔截器json

10、 spring mvc 轉發與重定向 (帶參數重定向)spring-mvc

11、 spring mvc 處理ajax請求mvc

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

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

十4、 spring mvc 多視圖控制器

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

spring mvc 核心類與接口

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

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類

無圖。

spring mvc 核心流程圖

spring mvc DispatcherServlet說明

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

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

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

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

先來看第一個例子:

<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

第二個例子:

<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> 這裏可使用多種寫法
一、不寫,使用默認值:/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

spring mvc 父子上下文的說明

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

<listener>    
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    
</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--小項目能作快--按激進方式作,一週時間就能夠出一個版本,先上線接受市場(用戶)的反饋,再改進,再反饋,時間就是生命(成本)。

springMVC-mvc.xml 配置文件片斷講解 

<?xml version="1.0" encoding="UTF-8"?>  
<beans  
    xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xmlns:tx="http://www.springframework.org/schema/tx"  
    xmlns:context="http://www.springframework.org/schema/context"    
    xmlns:mvc="http://www.springframework.org/schema/mvc"    
    xsi:schemaLocation="http://www.springframework.org/schema/beans   
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd   
    http://www.springframework.org/schema/tx   
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  
    http://www.springframework.org/schema/context  
    http://www.springframework.org/schema/context/spring-context-3.0.xsd  
    http://www.springframework.org/schema/mvc  
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">  
  
  
    <!-- 自動掃描的包名 -->  
    <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"/>  
  
</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。

spring mvc 如何訪問到靜態的文件,如jpg,js,css

若是你的DispatcherServlet攔截"*.do"這樣的有後綴的URL,就不存在訪問不到靜態資源的問題。
若是你的DispatcherServlet攔截"/",爲了實現REST風格,攔截了全部的請求,那麼同時對*.js,*.jpg等靜態文件的訪問也就被攔截了。
咱們要解決這個問題

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

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

<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 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/>

<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後綴,就不存上述問題了。仍是有後綴方便

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

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

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

11、 spring mvc 處理ajax請求

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

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

十4、 spring mvc 多視圖控制器

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

相關文章
相關標籤/搜索