SpringMVC使用註解@RequestMapping對映請求
SpringMVC通過使用@RequestMapping註解,實現指定控制器可以處理哪些URL請求。
控制器的類定義及方法定義處都可以標註@RequestMapping:
- 類定義處:提供初步的請求對映資訊。相對於WEB 應用的根目錄。
方法定義處:提供進一步的細分對映資訊。相對於類定義處的URL。若類定義處未標註@RequestMapping,則方法處標記的URL 相對於WEB 應用的根目錄。
下面測試一下,當我們僅在方法hello()處添加註解@RequestMapping(“/helloworld”)時,通過頁面超連結地址”helloworld”可以正常跳轉到success.jsp頁面:
現在我們新增類定義處的註解@RequestMapping(“/hello”):
那麼通過上面的超連結地址”helloworld”訪問則會提示:
必須將超連結地址改為”hello/helloworld”,才可以正常跳轉:
類定義處標記的@RequestMapping(“/hello”)限定了處理器類可以處理所有URL為/hello的請求,它相對於WEB容器部署的根路徑;而通過在方法處標記@RequestMapping註解,則可以實現讓處理器類定義多個處理方法,以處理來自/hello下的不同請求。
@RequestMapping除了可以使用請求URL對映請求外,還可以使用請求方法、請求引數及請求頭對映請求
標準的HTTP請求報頭格式如下:
@RequestMapping的value、method、params及headers 分別表示請求URL、請求方法、請求引數及請求頭的對映條件,他們之間是與的關係,聯合使用多個條件可讓請求對映更加精確化(params和headers不常用,瞭解即可)。method指定請求方式為GET或是POST,params的表示式格式如下:(headers與其類似)
- param1: 表示請求必須包含名為param1 的請求引數。
- !param1: 表示請求不能包含名為param1 的請求引數。
- param1 != value1: 表示請求包含名為param1 的請求引數,但其值不能為value1。
{“param1=value1”, “param2”}: 請求必須包含名為param1 和param2 的兩個請求引數,且param1引數的值必須為value1。
那麼比如我們現在可以將hello()方法註解為:
即該方法只會處理請求路徑為”hello/helloworld”,請求方法為GET,必須帶有引數userId和age,其中age值不能為10,且請求頭中Accept-Language要為zh-CN,zh;q=0.8的請求。
@RequestMapping對映的url還可以使用Ant風格的萬用字元
?:匹配檔名中的一個字元
*:匹配檔名中的任意字元
**:匹配多層路徑
例如,/user/*/createUser: 可以匹配 /user/aaa/createUser、/user/bbb/createUser等URL
@PathVariable可以對映URL繫結的佔位符
帶佔位符的URL 是Spring3.0 新增的功能,該功能在SpringMVC向REST目標挺進發展過程中具有里程碑的意義。通過@PathVariable可以將URL 中佔位符引數繫結到控制器處理方法的引數中:URL 中的{xxx} 佔位符可以通 過@PathVariable(“xxx”) 繫結到操作方法的入參中,注意兩個“xxx”必須一致。例如,我們可以將方法hello()註解為:
那麼,當我們在頁面中的請求格式為:
則可以在方法中獲取id值為5,並輸出到控制檯。
表現層狀態轉化REST(Representational State Transfer)
REST是目前最流行的一種網際網路軟體架構。它結構清晰、符合標準、易於理解、擴充套件方便,所以正得到越來越多網站的採用。解釋一下名詞:
資源(Resources):網路上的一個實體,或者說是網路上的一個具體資訊。它可以是一段文字、一張圖片、一首歌曲、一種服務,總之就是一個具體的存在。可以用一個URL(統一資源定位符)指向它,每種資源對應一個特定的URL。要獲取這個資源,訪問它的URL就可以,因此URL 即為每一個資源的獨一無二的識別符。
表現層(Representation):把資源具體呈現出來的形式,叫做它的表現層(Representation)。比如,文字可以用txt 格式表現,也可以用HTML 格式、XML 格式、JSON 格式表現,甚至可以採用二進位制格式。
狀態轉化(State Transfer):每發出一個請求,就代表了客戶端和伺服器的一次互動過程。HTTP協議,是一個無狀態協議,即所有的狀態都儲存在伺服器端。因此,如果客戶端想要操作伺服器,必須通過某種手段,讓伺服器端發生“狀態轉化”(State Transfer)。而這種轉化是建立在表現層之上的,所以就是“表現層狀態轉化”。具體說,就是HTTP 協議裡面,四個表示操作方式的動詞:GET、POST、PUT、DELETE。它們分別對應四種基本操作:GET 用來獲取資源,POST 用來新建資源,PUT 用來更新資源,DELETE 用來刪除資源。
示例:
– /order/1 HTTP GET:得到id= 1 的order
– /order/1 HTTP DELETE:刪除id = 1的order
– /order/1 HTTP PUT:更新id = 1的order
– /order HTTP POST:新增order
但是,瀏覽器form 表單只支援GET與POST請求,不支援DELETE和PUT 。Spring3.0 添加了一個過濾器HiddenHttpMethodFilter,它可以將DELETE和PUT請求轉換為標準的http 方法,使得支援GET、POST、PUT 與DELETE 請求。(檢視原始碼我們知道了HiddenHttpMethodFilter工作原理是當頁面傳送一個POST請求時,同時傳送一個隱藏域_method,根據_method值為DELETE或者PUT,過濾器HiddenHttpMethodFilter封裝一個新的請求傳給SpringMVC)
下面以DELETE請求為例,首先在web.xml中配置HiddenHttpMethodFilter:
<!-- 配置 org.springframework.web.filter.HiddenHttpMethodFilter: 可以把 POST
請求轉為 DELETE 或 PUT 請求 -->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
將控制器中的方法限定為只處理請求方法為DELETE的請求:
@Controller
@RequestMapping("/hello")
public class Hello {
@RequestMapping(value = "/helloworld/{id}", method = RequestMethod.DELETE)
public String hello(@PathVariable("id") Integer id) {
System.out.println("Test DELETE, id = " + id);
return "success";
}
}
頁面中的form表單為:
<form action="hello/helloworld/5" method="post">
<input type="hidden" name="_method" value="DELETE">
<input type="submit" value="Test REST DELETE">
</form>
測試:
成功跳轉:
控制檯正確輸出:
注:以上內容參考自佟剛老師的Spring MVC視訊教程。