Spring MVC 學習筆記(二):@RequestMapping用法詳解

來源:互聯網
上載者:User

標籤:

一、@RequestMapping 簡介

在Spring MVC 中使用 @RequestMapping 來映射請求,也就是通過它來指定控制器可以處理哪些URL請求,相當於Servlet中在web.xml中配置

<servlet>    <servlet-name>servletName</servlet-name>    <servlet-class>ServletClass</servlet-class></servlet><servlet-mapping>    <servlet-name>servletName</servlet-name>    <url-pattern>url</url-pattern></servlet-mapping>

的映射作用一致。讓我們先看一下RequestMapping註解類的源碼:

@Target({ElementType.METHOD, ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Mappingpublic @interface RequestMapping {String name() default "";String[] value() default {};String[] path() default {};RequestMethod[] method() default {};String[] params() default {};String[] headers() default {};String[] consumes() default {};String[] produces() default {};}

1)在@Target中有兩個屬性,分別為 ElementType.METHOD 和 ElementType.TYPE ,也就是說 @RequestMapping 可以在方法和類的聲明中使用

2)可以看到註解中的屬性除了 name() 返回的字串,其它的方法均返回數組,也就是可以定義多個屬性值,例如 value() 和 path() 都可以同時定義多個字串值來接收多個URL請求


二、準備工作:(註:後面的樣本都將基於準備工作)

1)建立一個 Web 工程,取名為 SpringMVC 

2)建立一個的控制器類:UserController

package cn.kolbe.spring.mvc.controller;import org.springframework.stereotype.Controller;@Controllerpublic class UserController {public String login() {return "success";}}

3)建立和配置 web.xml 以及 spring-mvc.xml 檔案

略(具體參見 前一章:?Spring MVC 學習筆記(一):HelloWorld?)

4)建立一個測試的 JSP 頁面 index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html><html><head><meta charset="UTF-8"><title>Spring MVC</title></head><body><p> <a href="#">User Login</a></body></html>

5)建立一個成功跳轉的頁面 JSP 頁面 welcome.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html><html><head><meta charset="UTF-8"><title>Spring MVC</title></head><body><h1>Welcome</h1></body></html>


三、測試 @RequestMapping 中的 value 和 path 屬性(這兩個屬性作用相同,可以互換,如果僅有這一個屬性,則可以省略,下面兩個例子均採用省略的方式)

1)將 @RequestMapping 註解在 login 方法上,而UserController上不添加 @RequestMapping 註解,這時的請求 URL 是相對於 Web 根目錄

@Controllerpublic class UserController {@RequestMapping("/login")public String login() {return "success";}}

這時的方法 login() 能處理的 URL 請求路徑是基於 Web 應用程式的,也就是 http://localhost/SpringMVC/login,也就是 index.jsp 頁面中的 User Login 連結地址應該是:

<a href="login">User Login</a>


2)將 @RequestMapping 註解在 UserController 類上,而UserController上不添加 @RequestMapping 註解,這時類的註解是相對於 Web 根目錄,而方法上的是相對於類上的路徑

@Controller@RequestMapping("/user")public class UserController {@RequestMapping("/login")public String login() {return "success";}}

這時的方法login()能處理的 URL 請求路徑則是 http://localhost/SpringMVC/user/login,也就是 index.jsp 頁面中的 User Login 連結地址應該是:

<a href="user/login">User Login</a>


四、測試 @RequestMapping 的 method 屬性

1)簡介:@RequestMapping 中的 method 主要用來定義接收瀏覽器發來的何種請求。在Spring中,使用枚舉類

org.springframework.web.bind.annotation.RequestMethod來定義瀏覽器請求的方式。

Http規範定義了多種請求資源的方式,最基本的有四種,分別為:GET(查)、POST(增)、PUT(改)、DELETE(刪),而URL則用於定位網路上的資源相當於地址的作用,配合四種請求方式,可以實現對URL對應的資源的增刪改查操作。

在實際應用中,很多人並沒有按照這個規範做,因為使用GET/POST同樣可以完成PUT和DELETE操作,甚至GET也可以完成POST操作,因為GET不需要用到表單,而POST卻需要通過表單來發送。

2)通過 @RequestMapping(value="/login",method=RequestMethod.GET) 來指定 login()方法 僅處理通過 GET 方式發來的請求

@Controller@RequestMapping(path = "/user")public class UserController {@RequestMapping(path = "/login", method=RequestMethod.GET)public String login() {return "success";}}

這時,如果瀏覽器發來的請求不是GET的話,將收到瀏覽器返回的錯誤提示,也就是得通過連結的方式而不是表單的方式:

<a href="user/login>User Login</a>

3)通過 @RequestMapping(value="/login",method=RequestMethod.POST) 來指定 login()方法 僅處理通過 POST 方式發來的請求

@Controller@RequestMapping(path = "/user")public class UserController {@RequestMapping(path = "/login", method=RequestMethod.POST)public String login() {return "success";}}

這時,必須通過表單的方式發送請求,否則將收到瀏覽器返回的錯誤提示

<form action="user/login" method="post">    <input type="submit" value="使用Post發送請求"/></form>

4)由於在 RequestMapping 註解類中 method() 方法返回的是 RequestMethod 數組,所以可以給 method 同時指定多個請求方式,例如:

@Controller@RequestMapping(path = "/user")public class UserController {        // 該方法將同時接收通過GET和POST方式發來的請求@RequestMapping(path = "/login", method={RequestMethod.POST,RequestMethod.GET})public String login() {return "success";}}


五、測試 @RequestMapping 的 params 屬性,該屬性工作表示請求參數,也就是追加在URL上的索引值對,多個請求參數以&隔開,例如:

http://localhost/SpringMVC/user/login?username=kolbe&password=123456

則這個請求的參數為username=kolbe以及password=123456,@RequestMapping 中可以使用 params 來限制請求參數,來實現進一步的過濾請求,舉個例子:

@Controller@RequestMapping(path = "/user")public class UserController {                // 該方法將接收 /user/login 發來的請求,且請求參數必須為 username=kolbe&password=123456@RequestMapping(path = "/login", params={"username=kolbe","password=123456"})public String login() {return "success";}}

該例中則表示 UserController 中的 login() 方法僅處理 /user/login 發來的請求,且必須帶有 username=kolbe&password=123456 的請求參數,否則瀏覽器將返回HTTP 404的錯誤, 對應 index.jsp 中的鍵接地址為:

<a href="user/login?username=kolbe&password=123456">User Login</a>


六、測試 @RequestMapping 的 headers 屬性,該屬性工作表示要求標頭

用於HTTP協義互動的資訊被稱為HTTP報文,用戶端發送的HTTP報文被稱為請求報文,伺服器發回給用戶端的HTTP報文稱為響應報文,報文由報文頭部和報文體組成。

要求標頭部(Request Headers):要求標頭包含許多有關用戶端環境和請求本文的資訊,例如瀏覽器支援的語言、請求的伺服器位址、用戶端的作業系統等。

回應標頭部(Rsponse Headers):回應標頭也包含許多有用的資訊,包括伺服器類型、日期、響應內容的類型及編碼,響應內容的長度等等。

如果你安裝的是Chrome瀏覽器,可以通過在網頁中  右擊滑鼠---->審查元素---->Network---->Name中點擊網頁---->右側查看Headers即可,如果Name中沒有出現網頁,可以重新整理一下即可,下邊是我電腦中的一個要求標頭部樣本:

Request Headers    Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8    Accept-Encoding:gzip, deflate, sdch    Accept-Language:zh-CN,zh;q=0.8    Cache-Control:max-age=0    Connection:keep-alive    Cookie:JSESSIONID=210075B5E521CWE3CDE938076295A57A    Host:localhost:8080    Upgrade-Insecure-Requests:1    User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93

回規正題,通過 @RequestMapping 中的 headers 屬性,可以限制用戶端發來的請求

@Controller@RequestMapping(path = "/user")public class UserController {        // 表示只接收本機發來的請求@RequestMapping(path = "/login", headers="Host=localhost:8080")public String login() {return "success";}}


七、帶預留位置的URL

(一)帶預留位置的URL是Spring 3.0 新增的功能,可以通過 @PathVariable 將 URL 中的預留位置綁定到控制器的處理方法的參數中,預留位置使用{}括起來

(二)使用方法:

1)帶預留位置的URL樣本:

@Controller@RequestMapping(path = "/user")public class UserController {        @RequestMapping(value="/{id}", method=RequestMethod.GET)public String show(@PathVariable("id") Integer id) {return "success";}}

在這個控制器中 show() 方法將可以接收 user/1、user/2、user/3等等的路徑請求,請求的方法必須為GET,使用 @PathVariable 為應用實現 REST 規範提供了具大的便利條件。


八、採用 REST 風格的 URL 請求

1)簡介:REST(Representational State Transfer):(資源)表現層狀態轉化,它是目前最流行的一種軟體架構,其結構清晰、易於理解、擴充方便且符合標準,正在越來越多的被實踐到應用中。

2)REST 風格的 URL 請求

 請求路徑        要求方法           作用-/user/1        HTTP GET        得到id為1的user-/user/1        HTTP DELETE     刪除id為1的user-/user/1        HTTP PUT        更新id為1的user-/user          HTTP POST       新增user

3)由於瀏覽器表單只支援 GET 和 POST 請求,為了實現 DELETE 和 PUT 請求,Spring 為我們提供了一個過濾器org.springframework.web.filter.HiddenHttpMethodFilter,可以為我們將 GET 和 POST 請求通過過濾器轉化成 DELETE 和 PUT 請求。

4)在 web.xml 中配置過濾器

<!-- 配置 org.springframework.web.filter.HiddenHttpMethodFilter 過濾器 --><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>

5)由於瀏覽器表單無法發送 DELETE 和 PUT 請求,所以為了讓 HiddenHttpMethodFilter 識別請求的方法,需要在表單中添加一個隱藏欄位,名字為 _method 值為 DELETE 或 POST 或PUT,修改後 index.jsp 頁面代碼如下:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html><html><head><meta charset="UTF-8"><title>Spring MVC</title></head><body><p> <!-- 得到id為1的user --><a href="user/1">Test Rest GET</a><!-- 建立id為1的user --><form action="user" method="post">        <input type="hidden" name="_method" value="POST"/><input type="submit" value="Test Rest POST"/></form><!-- 刪除id為1的user --><form action="user/1" method="post"><input type="hidden" name="_method" value="DELETE"/><input type="submit" value="Test Rest DELETE"/></form><!-- 更新id為1的user --><form action="user/1" method="post"><input type="hidden" name="_method" value="PUT"/><input type="submit" value="Test Rest PUT"/></form></body></html>

6)修改後的UserController代碼

package cn.kolbe.spring.mvc.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;@Controller@RequestMapping(path = "/user")public class UserController {@RequestMapping(value="/{id}", method=RequestMethod.GET)public String show(@PathVariable("id") Integer id) {System.out.println("查看id為:" + id + "的user");return "success";}@RequestMapping(value="/{id}", method=RequestMethod.PUT)public String update(@PathVariable("id") Integer id) {System.out.println("更新id為:" + id + "的user");return "success";}@RequestMapping(value="/{id}", method=RequestMethod.DELETE)public String destroy(@PathVariable("id") Integer id) {System.out.println("刪除id為:" + id + "的user");return "success";}@RequestMapping(value="", method=RequestMethod.POST)public String create() {System.out.println("建立user");return "success";}}


註:如果你的web項目是運行在Tomcat 8下,你會發現被過濾成DELETE和PUT請求,到達控制器後,返回時(forward)會報HTTP 405的錯誤提示

HTTP Status 405 - Request method ‘DELETE‘ not supported或HTTP Status 405 - JSPs only permit GET POST or HEAD

有三種解決方案:

(一)將 Tomcat 8 改為 Tomcat 7,在Tomcat 7 下運行是正常的

(二)將請求轉寄(forward)改為請求重新導向(redirect)

(三)自己手動寫一個Filter來封裝HttpRequest中的getMethod()方法





Spring MVC 學習筆記(二):@RequestMapping用法詳解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.