天天看點

Spring MVC配置介紹

spring mvc就是spring架構對mvc設計模式的實作,通過spring mvc ,我們可以快速的建構靈活、松耦合的web服務。再具體介紹spring mvc 之前,我們先看一下它的請求處理過程:

Spring MVC配置介紹

其實spring mvc的核心就是dispatchservlet,配置spring mvc的過程就是配置dispatchservlet的過程。

spring的配置有兩種方式,一種通過web.xml配置,另一種就是通過java配置,在這裡我們主要講如何在web.xml中配置:

主要配置項:

<code>&lt;context-param&gt;</code>和<code>&lt;listener&gt;</code>:配置spring的<code>rootcontext</code>,對應配置檔案為<code>root-context.xml</code>

<code>&lt;servlet&gt;</code>和<code>&lt;servlet-mapping&gt;</code>:配置spring的<code>webcontext</code>,對應配置檔案預設為為<code>web-inf/{servlet-name}-servlet.xml</code>

可能有些人還不太清楚為什麼要這樣配置,在具體講解之前,先介紹spring mvc中的兩個context(上下文)。

了解兩個context

我們知道,spring有一個核心容器也就是applicationcontext,所有的spring元件都由這個applicationcontext進行管理。但是在web項目中,spring會維護兩個context:

Spring MVC配置介紹

1. webcontext

第一個context就是由dispatchservlet建立的webcontext,負責裝載web元件相關的bean,比如controllers、view resolvers、handler mapping等,對應的配置檔案是<code>web-inf/{servlet-name}-servlet.xml</code>,在上面例子中我們配置的servlet的名字是spring,是以它預設加載spring-servlet.xml配置檔案作為上下文。

但是我們也可以自己指定一個webcontext配置檔案位置,比如指定/web-inf/spring/appservlet/servlet-context.xml路徑下的配置檔案:

2. rootcontext

rootcontext是由contextlistener加載的,它主要裝載除web元件之外的應用程式元件,比如jdbc、mybatis等元件。<code>&lt;context-param&gt;</code>标簽指定了rootcontext配置檔案的位置,并由<code>&lt;listener&gt;</code>标簽指定的listener類進行裝載。

上面的配置其實已經基本ok了,但是一個完整的spring mvc應用還需要controller、service、view等web元件,是以我們還要在配置中啟用注解及自動包掃描等功能,友善web元件的自動發現,這些應該在上面介紹的webcontext對應的配置檔案中進行配置,也就是在spring-servlet.xml中配置:

<code>&lt;mvc:annotation-driven/&gt;</code>标簽作用是開啟注解

<code>&lt;context:component-scan/&gt;</code>标簽目的是啟用自動包掃描,這樣spring架構就會自動掃描被注解的類,納入到webcontext中。

通過上面的配置,spring mvc的主要配置就已經完成了,我們現在就可以編寫spring mvc的元件了,我們先從controller開始。

聲明controller元件:寫一個controller很簡單,@controller注解聲明目前類是一個controller類,上面配置中我們開啟了componentscan,被@controller注解的類會被自動裝載到spring application context中。當然我們使用@component元件效果也是一樣的,隻不過@controller更能展現controller角色。

定義請求路徑: homecontroller類裡面隻有一個home()方法,并且還攜帶一個@requestmapping注解,注解中的value屬性定義了這個方法的通路路徑是“/”,method屬性定義了這個方法隻處理get請求。

定義渲染view:我們可以看到,home()方法很簡單,僅傳回了一個“home”字元串。預設情況下,方法傳回的字元串預設會被解析成view的名稱,dispatcherservlet 會讓viewresolver解析這個view名稱對應的真是view頁面。我們上面已經配置了一個internalresourceviewresolver,傳回的home會被解析/web-inf/views/home.jsp。

寫完controller之後我們可以通過測試類測試一下,寫一個測試controller:

其實<code>@requestmapping</code>注解既可以注解方法又可以注解類,當注解類時,通路類中所有的方法就必須加上類路徑。另外<code>@requestmapping</code>中的值可以是一個路徑數組,當傳入一個數組時,我們可以通過數組中的任何一個路徑通路到這個類.

我們知道通常情況下,controller處理完業務後會傳回結果資料給view層。為此,springmvc提供了model類來封裝結果資料,封裝的過程是自動的,我們隻需要在方法中加入model參數即可:

model其實就是一個map,view層會自動解析model中的資料,然後渲染結果給client端。上面的<code>model.addattribute</code>方法沒有指定key,key值會被預設設定為對象的類型名,比如上例子中對象類型是<code>list&lt;user&gt;</code>,則key值預設為:<code>userlist</code>。方法最後傳回的string值<code>userview</code>會直接作為view的名稱。

當然我們也可以明确指定傳回資料模型的key值:

如果我們不想使用spring的model類,我們也可以用java.util.map類替換model,這兩個效果是完全一樣的:

除了上面兩種方式之外,我們還可以這麼寫:

這種方式比較特殊,我們既沒有設定傳回的model,又沒有指定渲染model的view,僅僅傳回處理的結果對象。遇到這種情況時,spring mvc會把傳回的對象會自動放入model中,其key就是對象的類型名,即<code>userlist</code>。而對應的view名稱則預設與請求路徑名一緻,例如我們的請求路徑是這樣:

那麼對應渲染結果的view就是<code>users</code>。

springmvc提供了多種資料傳輸方式:

queryparameter:查詢參數

form parameters:表單參數

path variables:路徑變量

下面我們逐一說明。

首先什麼是查詢參數呢?比如我們有一個這樣的請求<code>http://localhost:8080/user/queryusers?pageno=1&amp;count=5</code>,在這個請求中,參數值都是通過url中?後面的參數傳遞過來的,這種方式就是查詢參數傳值。如果要解析查詢參數中的值,我們需要用到@requestparam注解,它會将請求參數映射到方法參數:

需要注意的是,我們在配置請求參數時可以指定參數的預設值,當client端傳過來的參數值不存在或者為空時,就會采用這個預設值,還有一點,因為查詢參數都是string類型,是以這裡的預設值也都是string類型。

除了通過查詢參數傳遞參數值之外,還有一種流行的方式就是通過請求路徑傳遞參數值,特别是在讨論建構基于資源的服務時會經常用到這種方式。(注:基于資源的服務可以簡單看做所有請求都是針對資源,所有的傳回結果也是資源)

比如我們有一個根據使用者id查詢使用者資訊的需求,通過上面介紹的方式我們可以這麼做:

那麼我們客戶的的請求路徑應該是這樣:<code>/employee/queryemployee ?employeeid=12345</code>,盡管也可以滿足需求,但這樣不太符合基于資源的理念。理想的情況是,資源應該是由請求路徑決定的,而不是由請求參數決定。或者說,請求參數不應該被用來描述一個資源。<code>/employee/12345</code> 這種請求方式顯然比<code>/employee/queryemployee ?employeeid=12345</code>更能合适,前者定義了要查詢的資源,而後者更強調了通過參數進行操作。

為了達到建構基于資源的controller這個目标,spring mvc允許請求路徑中包含一個占位符,占位符名稱需要用一對{}括起來。在客戶的請求資源時,請求路徑的其它部分還是用來比對資源路徑,而占位符部分則直接用來傳輸參數值。下面就是通過占位符的方式實作路徑中傳遞參數值:

上面例子可以看到,方法參數中有一個<code>@pathvariable</code>的注解,這個注解的意思就是不管請求路徑中占位符處的值是什麼,它都會被傳遞到<code>@pathvariable</code>注解的變量中。比如按照上面的配置,如果我們的請求是<code>/employee/12345</code>,則<code>123456</code>便會傳入變成<code>userid</code>的值。需要注意的是,如果方法參數值和占位符名稱一樣,我們也可以省略<code>@pathvariable</code>中的屬性值:

在請求的資料量很小的時候使用查詢參數和路徑參數還是可行的,但是有時候我們請求的資料量會很大,再用上面兩種方式就顯得有點不太合适,這時就需要考慮用第三種方式:表單參數。

一個web應用不單單隻是給使用者展示資料,很多時候它還需要與使用者互動擷取使用者資料,表單就是擷取使用者資料最常見的方式。

比如我們有個系統資料庫單:

表單都是以post方式送出的,是以我們的controller接受的應該是個post請求:

在上面例子中,出了接收的請求是post之外,注冊方法還有一個含有user對象的參數,這個user對象中含有name、password、accountno屬性,springmvc會根據名稱從請求中解析相同名稱參數并指派到對象屬性中。

當注冊方法儲存使用者資訊之後,會傳回一個字元串<code>redirect:/user/</code>,這個字元串與前面講到的都不同,它傳回的并不是一個view的名稱,而是一個redirect重定向請求。因為傳回的字元串中含有一個<code>redirect:</code>重定向關鍵字,當<code>internalresourceviewresolver</code>類遇到這個關鍵字時,它将會攔截這個字元串并把它解析成一個重定向請求而不是view名稱。

<code>internalresourceviewresolver</code>除了能夠識别redirect:關鍵字之外,它還能識别<code>forward:</code>關鍵字,并把包含<code>forward:</code>關鍵字的字元串解析成<code>forward</code>請求。

在spring3.0以後,springmvc便支援java validation api了,java validation api提供了一些注解來限制對象屬性值,這些注解有:

注解

解釋

@assertfalse

the annotated element must be a boolean type and be false.

@asserttrue

the annotated element must be a boolean type and be true.

@decimalmax

the annotated element must be a number whose value is less than or equal toa given bigdecimalstring value.

@decimalmin

the annotated element must be a number whose value is greater than orequal to a given bigdecimalstring value.

@digits

the annotated element must be a number whose value has a specified number of digits.

@future

the value of the annotated element must be a date in the future.

@max

the annotated element must be a number whose value is less than or equal to a given value.

@min

the annotated element must be a number whose value is greater than or equal to a given value.

@notnull

the value of the annotated element must not be null.

@null

the value of the annotated element must be null.

@past

the value of the annotated element must be a date in the past.

@pattern

the value of the annotated element must match a given regular expression.

@size

the value of the annotated element must be either a string, a collection, or an array whose length fits within the given range.

我們可以利用這些注解給user對象添加一些驗證,比如非空和字元串長度驗證:

我們還需要通過<code>@valid</code>标簽在方法中對user啟用參數驗證:

在上面例子中,我們在方法中的user參數前面添加了@valid注解,這個注解會告訴spring架構需要啟用對這個對象的驗證。如果發現任何驗證錯誤,錯誤資訊都将會被封裝到errors對象中,我們可以通過<code>errors.haserrors()</code>方法判斷是否驗證通過。

<a href="http://blog.csdn.net/suifeng3051/article/details/51648360">spring mvc 頁面渲染( render view )</a>

<a href="http://blog.csdn.net/suifeng3051/article/details/51672238">spring mvc 中的異常處理 (handling exceptions)</a>

<a href="http://blog.csdn.net/suifeng3051/article/details/51659731">spring mvc 上傳檔案(upload files)</a>