2. RequestMapping註解

捞月亮的小北發表於2024-06-25

1. RequestMapping的作用

@RequestMapping​ 註解是 Spring MVC 框架中的一個控制器對映註解,用於將請求對映到相應的處理方法上。具體來說,它可以將指定 URL 的請求繫結到一個特定的方法或類上,從而實現對請求的處理和響應。

2. RequestMapping的出現位置

img

透過RequestMapping的原始碼可以看到RequestMapping註解只能出現在類上或者方法上。

3. 類上與方法上結合使用

我們先來看,在同一個web應用中,是否可以有兩個完全一樣的RequestMapping。測試一下:假設兩個RequestMapping,其中一個是展示使用者詳細資訊,另一個是展示商品詳細資訊。提供兩個Controller,一個是UserController,另一個是ProductController。如下:

package com.powernode.springmvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * ClassName: UserController
 * Description:
 * Datetime: 2024/3/13 16:40
 * Author: 老杜@動力節點
 * Version: 1.0
 */
@Controller
public class UserController {
    @RequestMapping("/detail")
    public String toDetail(){
        return "detail";
    }
}
package com.powernode.springmvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * ClassName: ProductController
 * Description:
 * Datetime: 2024/3/13 16:40
 * Author: 老杜@動力節點
 * Version: 1.0
 */
@Controller
public class ProductController {
    @RequestMapping("/detail")
    public String toDetail(){
        return "detail";
    }
}

以上兩個Controller的RequestMapping相同,都是"/detail",我們來啟動伺服器看會不會出現問題:異常發生了,異常資訊如下

org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping': 
Ambiguous mapping. Cannot map 'userController' method 
com.powernode.springmvc.controller.UserController#toDetail()
to { [/detail]}: There is already 'productController' bean method
com.powernode.springmvc.controller.ProductController#toDetail() mapped.

以上異常資訊大致的意思是:不明確的對映。無法對映UserController中的toDetail()方法,因為已經在ProductController中對映過了!!!!

透過測試得知,在同一個webapp中,RequestMapping必須具有唯一性。怎麼解決以上問題?兩種解決方案:

  • 第一種方案:將方法上RequestMapping的對映路徑修改的不一樣。
  • 第二種方案:在類上新增RequestMapping的對映路徑,以類上的RequestMapping作為名稱空間,來加以區分兩個不同的對映。

3.1. 第一種方案

將方法上RequestMapping的對映路徑修改的不一樣。

@RequestMapping("/user/detail")
public String toDetail(){
    return "/user/detail";
}
@RequestMapping("/product/detail")
public String toDetail(){
    return "/product/detail";
}

再次啟動web伺服器,會發現沒有再報錯了。

為這兩個請求分別提供對應的檢視頁面:

img

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>商品詳情頁面</title>
</head>
<body>
<h1>商品詳情</h1>
</body>
</html>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>使用者詳情頁面</title>
</head>
<body>
<h1>使用者詳情</h1>
</body>
</html>

在首頁面新增兩個超連結:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>index page</title>
</head>
<body>
<h1>index page</h1>
<a th:href="@{/user/detail}">使用者詳情</a><br>
<a th:href="@{/product/detail}">商品詳情</a><br>
</body>
</html>

啟動Tomcat伺服器,並測試:http://localhost:8080/springmvc/

img

點選使用者詳情,點選商品詳情,都可以正常顯示:

img

img

img

3.2. 第二種方案

在類上和方法上都使用RequestMapping註解來進行路徑的對映。假設在類上對映的路徑是"/a",在方法上對映的路徑是"/b",那麼整體表示對映的路徑就是:"/a/b"

在第一種方案中,假設UserController類中有很多方法,每個方法的 RequestMapping註解中都需要以"/user"開始,顯然比較囉嗦,乾脆將"/user"提升到類級別上,例如:

package com.powernode.springmvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * ClassName: UserController
 * Description:
 * Datetime: 2024/3/13 16:40
 * Author: 老杜@動力節點
 * Version: 1.0
 */
@Controller
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/detail")
    public String toDetail(){
        return "/user/detail";
    }
}
package com.powernode.springmvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * ClassName: ProductController
 * Description:
 * Datetime: 2024/3/13 16:40
 * Author: 老杜@動力節點
 * Version: 1.0
 */
@Controller
@RequestMapping("/product")
public class ProductController {
    @RequestMapping("/detail")
    public String toDetail(){
        return "/product/detail";
    }
}

經過測試,程式可以正常執行!!!

img

4. RequestMapping註解的value屬性

4.1. value屬性的使用

value屬性是該註解最核心的屬性,value屬性填寫的是請求路徑,也就是說透過該請求路徑與對應的控制器的方法繫結在一起。另外透過原始碼可以看到value屬性是一個字串陣列:

img

既然是陣列,就表示可以提供多個路徑,也就是說,在SpringMVC中,多個不同的請求路徑可以對映同一個控制器的同一個方法:

編寫新的控制器:

package com.powernode.springmvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * ClassName: RequestMappingTestController
 * Description: 測試 RequestMapping 註解
 * Datetime: 2024/3/14 9:14
 * Author: 老杜@動力節點
 * Version: 1.0
 */
@Controller
public class RequestMappingTestController {
    @RequestMapping(value = {"/testValue1", "/testValue2"})
    public String testValue(){
        return "testValue";
    }
}

提供檢視頁面:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>test Value</title>
</head>
<body>
<h1>Test RequestMapping's Value</h1>
</body>
</html>

在index.html檔案中新增兩個超連結:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>index page</title>
</head>
<body>
<h1>index page</h1>
<a th:href="@{/user/detail}">使用者詳情</a><br>
<a th:href="@{/product/detail}">商品詳情</a><br>

<!--測試RequestMapping的value屬性-->
<a th:href="@{/testValue1}">testValue1</a><br>
<a th:href="@{/testValue2}">testValue2</a><br>

</body>
</html>

啟動伺服器,測試,點選以下的兩個超連結,傳送請求,都可以正常訪問到同一個控制器上的同一個方法:

img

img

img

img

4.2. Ant風格的value

value是可以用來匹配路徑的,路徑支援模糊匹配,我們把這種模糊匹配稱之為Ant風格。關於路徑中的萬用字元包括:

  • ?,代表任意一個字元
  • *,代表0到N個任意字元
  • **,代表0到N個任意字元,並且路徑中可以出現路徑分隔符 /

注意:** 萬用字元在使用時,左右不能出現字元,只能是 /

測試一下這些萬用字元,在 RequestMappingTestController 中新增以下方法:

@RequestMapping("/x?z/testValueAnt")
public String testValueAnt(){
    return "testValueAnt";
}

提供檢視頁面:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>test Value Ant</title>
</head>
<body>
<h1>測試RequestMapping註解的value屬性支援模糊匹配</h1>
</body>
</html>

在index.html頁面中編寫超連結:

<!--測試RequestMapping註解的value屬性支援模糊匹配-->
<a th:href="@{/xyz/testValueAnt}">測試value屬性的模糊匹配</a><br>

測試結果如下:

img

img

透過修改瀏覽器位址列上的路徑,可以反覆測試萬用字元 ? 的語法:

img

img

img

img

img

img

img

將 ? 萬用字元修改為 * 萬用字元:

//@RequestMapping("/x?z/testValueAnt")
@RequestMapping("/x*z/testValueAnt")
public String testValueAnt(){
    return "testValueAnt";
}

開啟瀏覽器直接在位址列上輸入路徑進行測試:

img

img

img

將 * 萬用字元修改為 ** 萬用字元:

@RequestMapping("/x**z/testValueAnt")
public String testValueAnt(){
    return "testValueAnt";
}

img

注意:/x**z/ 實際上並沒有使用萬用字元 **,本質上還是使用的 *,因為萬用字元 ** 在使用的時候,左右兩邊都不能有任何字元,必須是 /。

@RequestMapping("/**/testValueAnt")
public String testValueAnt(){
    return "testValueAnt";
}

啟動伺服器發現報錯了:

img

以上寫法在Spring5的時候是支援的,但是在Spring6中進行了嚴格的規定,** 萬用字元只能出現在路徑的末尾,例如:

@RequestMapping("/testValueAnt/**")
public String testValueAnt(){
    return "testValueAnt";
}

測試結果:

img

img

4.3. value中的佔位符(重點)

到目前為止,我們的請求路徑是這樣的格式:uri?name1=value1&name2=value2&name3=value3

其實除了這種方式,還有另外一種格式的請求路徑,格式為:uri/value1/value2/value3,我們將這樣的請求路徑叫做 RESTful 風格的請求路徑。

RESTful風格的請求路徑在現代的開發中使用較多。

普通的請求路徑:http://localhost:8080/springmvc/login?username=admin&password=123&age=20

RESTful風格的請求路徑:http://localhost:8080/springmvc/login/admin/123/20

如果使用RESTful風格的請求路徑,在控制器中應該如何獲取請求中的資料呢?可以在value屬性中使用佔位符,例如:/login/{id}/{username}/{password}

在 RequestMappingTestController 類中新增一個方法:

@RequestMapping(value="/testRESTful/{id}/{username}/{age}")
public String testRESTful(
        @PathVariable("id")
        int id,
        @PathVariable("username")
        String username,
        @PathVariable("age")
        int age){
    System.out.println(id + "," + username + "," + age);
    return "testRESTful";
}

提供檢視頁面:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>test RESTful</title>
</head>
<body>
<h1>測試value屬性使用佔位符</h1>
</body>
</html>

在 index.html 頁面中新增超連結:

<!--測試RequestMapping註解的value屬性支援佔位符-->
<a th:href="@{/testRESTful/1/zhangsan/20}">測試value屬性使用佔位符</a>

啟動伺服器測試:

img

img

img

img

5. RequestMapping註解的method屬性

5.1. method屬性的作用

在Servlet當中,如果後端要求前端必須傳送一個post請求,後端可以透過重寫doPost方法來實現。後端要求前端必須傳送一個get請求,後端可以透過重寫doGet方法來實現。當重寫的方法是doPost時,前端就必須傳送post請求,當重寫doGet方法時,前端就必須傳送get請求。如果前端傳送請求的方式和後端的處理方式不一致時,會出現405錯誤。

HTTP狀態碼405,這種機制的作用是:限制客戶端的請求方式,以保證伺服器中資料的安全。

假設後端程式要處理的請求是一個登入請求,為了保證登入時的使用者名稱和密碼不被顯示到瀏覽器的位址列上,後端程式有義務要求前端必須傳送一個post請求,如果前端傳送get請求,則應該拒絕。

那麼在SpringMVC框架中應該如何實現這種機制呢?可以使用RequestMapping註解的method屬性來實現。

透過RequestMapping原始碼可以看到,method屬性也是一個陣列:

img

陣列中的每個元素是 RequestMethod,而RequestMethod是一個列舉型別的資料:

img

因此如果要求前端傳送POST請求,該註解應該這樣用:

@RequestMapping(value = "/login", method = RequestMethod.POST)
public String login(){
    return "success";
}

接下來,我們來測試一下:

在RequestMappingTestController類中新增以下方法:

@RequestMapping(value="/login", method = RequestMethod.POST)
public String testMethod(){
    return "testMethod";
}

提供檢視頁面:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>test Method</title>
</head>
<body>
<h1>Login Success!!!</h1>
</body>
</html>

img

在index.html頁面中提供一個登入的form表單,後端要求傳送post請求,則form表單的method屬性應設定為post:

<!--測試RequestMapping的method屬性-->
<form th:action="@{/login}" method="post">
    使用者名稱:<input type="text" name="username"/><br>
    密碼:<input type="password" name="password"/><br>
    <input type="submit" value="登入">
</form>

啟動伺服器,測試:

img

img

img

透過測試,前端傳送的請求方式post,後端處理請求的方式也是post,就不會有問題。

當然,如果後端要求前端必須傳送post請求,而前端傳送了get請求,則會出現405錯誤,將index.html中form表單提交方式修改為get:

<!--測試RequestMapping的method屬性-->
<form th:action="@{/login}" method="get">
    使用者名稱:<input type="text" name="username"/><br>
    密碼:<input type="password" name="password"/><br>
    <input type="submit" value="登入">
</form>

再次測試:

img

因此,可以看出,對於RequestMapping註解來說,多一個屬性,就相當於多了一個對映的條件,如果value和method屬性都有,則表示只有前端傳送的請求路徑 + 請求方式都滿足時才能與控制器上的方法建立對映關係,只要有一個不滿足,則無法建立對映關係。例如:@RequestMapping(value="/login", method = RequestMethod.POST) 表示當前端傳送的請求路徑是 /login,並且傳送請求的方式是POST的時候才會建立對映關係。如果前端傳送的是get請求,或者前端傳送的請求路徑不是 /login,則都是無法建立對映的。

img

5.2. 衍生Mapping

對於以上的程式來說,SpringMVC提供了另一個註解,使用這個註解更加的方便,它就是:PostMapping,使用該註解時,不需要指定method屬性,因為它預設採用的就是POST處理方式:修改RequestMappingTestController程式碼如下

//@RequestMapping(value="/login", method = RequestMethod.POST)
@PostMapping("/login")
public String testMethod(){
    return "testMethod";
}

當前端傳送get請求時,測試一下:

img

當前端傳送post請求時,測試一下:

img

在SpringMVC中不僅提供了 PostMaping註解,像這樣的註解還有四個,包括:

  • GetMapping:要求前端必須傳送get請求
  • PutMapping:要求前端必須傳送put請求
  • DeleteMapping:要求前端必須傳送delete請求
  • PatchMapping:要求前端必須傳送patch請求

img

5.3. web的請求方式

前端向伺服器傳送請求的方式包括哪些?共9種,前5種常用,後面作為了解:

  • GET:獲取資源,只允許讀取資料,不影響資料的狀態和功能。使用 URL 中傳遞引數或者在 HTTP 請求的頭部使用引數,伺服器返回請求的資源。
  • POST:向伺服器提交資源,可能還會改變資料的狀態和功能。透過表單等方式提交請求體,伺服器接收請求體後,進行資料處理。
  • PUT:更新資源,用於更新指定的資源上所有可編輯內容。透過請求體傳送需要被更新的全部內容,伺服器接收資料後,將被更新的資源進行替換或修改。
  • DELETE:刪除資源,用於刪除指定的資源。將要被刪除的資源識別符號放在 URL 中或請求體中。
  • HEAD:請求伺服器返回資源的頭部,與 GET 命令類似,但是所有返回的資訊都是頭部資訊,不能包含資料體。主要用於資源檢測和快取控制。
  • PATCH:部分更改請求。當被請求的資源是可被更改的資源時,請求伺服器對該資源進行部分更新,即每次更新一部分。
  • OPTIONS:請求獲得伺服器支援的請求方法型別,以及支援的請求頭標誌。“OPTIONS *”則返回支援全部方法型別的伺服器標誌。
  • TRACE:伺服器響應輸出客戶端的 HTTP 請求,主要用於除錯和測試。
  • CONNECT:建立網路連線,通常用於加密 SSL/TLS 連線。

注意:

  1. 使用超連結以及原生的form表單只能提交get和post請求,put、delete、head請求可以使用傳送ajax請求的方式來實現。
  2. 使用超連結傳送的是get請求
  3. 使用form表單,如果沒有設定method,傳送get請求
  4. 使用form表單,設定method="get",傳送get請求
  5. 使用form表單,設定method="post",傳送post請求
  6. 使用form表單,設定method="put/delete/head",傳送get請求。(針對這種情況,可以測試一下)

將index.html中登入表單的提交方式method設定為put:

<!--測試RequestMapping的method屬性-->
<form th:action="@{/login}" method="put">
    使用者名稱:<input type="text" name="username"/><br>
    密碼:<input type="password" name="password"/><br>
    <input type="submit" value="登入">
</form>

修改RequestMappingTestController類的程式碼:

@RequestMapping(value="/login", method = RequestMethod.PUT)
//@PostMapping("/login")
public String testMethod(){
    return "testMethod";
}

測試結果:

img

透過測試得知,即使form中method設定為put方式,但仍然採用get方式傳送請求。

再次修改RequestMappingTestController:

@RequestMapping(value="/login", method = RequestMethod.GET)
//@PostMapping("/login")
public String testMethod(){
    return "testMethod";
}

再次測試:

img

5.4. GET和POST的區別

在之前釋出的JavaWEB影片中對HTTP請求協議的GET和POST進行了詳細講解,這裡就不再贅述,大致回顧一下。

HTTP請求協議之GET請求:

GET /springmvc/login?username=lucy&userpwd=1111 HTTP/1.1                           請求行
Host: localhost:8080                                                                    請求頭
Connection: keep-alive
sec-ch-ua: "Google Chrome";v="95", "Chromium";v="95", ";Not A Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: http://localhost:8080/springmvc/index.html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
                                                                                        空白行
                                                                                        請求體

HTTP請求協議之POST請求:

POST /springmvc/login HTTP/1.1                                                  請求行
Host: localhost:8080                                                                  請求頭
Connection: keep-alive
Content-Length: 25
Cache-Control: max-age=0
sec-ch-ua: "Google Chrome";v="95", "Chromium";v="95", ";Not A Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
Origin: http://localhost:8080
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: http://localhost:8080/springmvc/index.html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
                                                                                      空白行
username=lisi&userpwd=123                                                             請求體

5.4.1. 區別是什麼

  1. get請求傳送資料的時候,資料會掛在URI的後面,並且在URI後面新增一個“?”,"?"後面是資料。這樣會導致傳送的資料回顯在瀏覽器的位址列上。

http://localhost:8080/springmvc/login?username=zhangsan&userpwd=1111

  1. post請求傳送資料的時候,在請求體當中傳送。不會回顯到瀏覽器的位址列上。也就是說post傳送的資料,在瀏覽器位址列上看不到。
  2. get請求只能傳送普通的字串。並且傳送的字串長度有限制,不同的瀏覽器限制不同。這個沒有明確的規範。get請求無法傳送大資料量。
  3. post請求可以傳送任何型別的資料,包括普通字串,流媒體等資訊:影片、聲音、圖片。post請求可以傳送大資料量,理論上沒有長度限制。
  4. get請求在W3C中是這樣說的:get請求比較適合從伺服器端獲取資料。
  5. post請求在W3C中是這樣說的:post請求比較適合向伺服器端傳送資料。
  6. get請求是安全的。因為在正確使用get請求的前提下,get請求只是為了從伺服器上獲取資料,不會對伺服器資料進行修改。
  7. post請求是危險的。因為post請求是修改伺服器端的資源。
  8. get請求支援快取。 也就是說當第二次傳送get請求時,會走瀏覽器上次的快取結果,不再真正的請求伺服器。(有時需要避免,怎麼避免:在get請求路徑後新增時間戳)
  9. post請求不支援快取。每一次傳送post請求都會真正的走伺服器。

5.4.2. 怎麼選擇

  1. 如果你是想從伺服器上獲取資源,建議使用GET請求,如果你這個請求是為了向伺服器提交資料,建議使用POST請求。
  2. 大部分的form表單提交,都是post方式,因為form表單中要填寫大量的資料,這些資料是收集使用者的資訊,一般是需要傳給伺服器,伺服器將這些資料儲存/修改等。
  3. 如果表單中有敏感資訊,建議使用post請求,因為get請求會回顯敏感資訊到瀏覽器位址列上。(例如:密碼資訊)
  4. 做檔案上傳,一定是post請求。要傳的資料不是普通文字。
  5. 其他情況大部分都是使用get請求。

img

6. RequestMapping註解的params屬性

6.1. params屬性的理解

params屬性用來設定透過請求引數來對映請求。

對於RequestMapping註解來說:

  • value屬性是一個陣列,只要滿足陣列中的任意一個路徑,就能對映成功
  • method屬性也是一個陣列,只要滿足陣列中任意一個請求方式,就能對映成功。
  • params屬性也是一個陣列,不過要求請求引數必須和params陣列中要求的所有引數完全一致後,才能對映成功。

img

img

6.2. params屬性的4種用法

  1. @RequestMapping(value="/login", params={ "username" , "password"}) 表示:請求引數中必須包含 username 和 password,才能與當前標註的方法進行對映。
  2. @RequestMapping(value="/login", params={ "!username" , "password"}) 表示:請求引數中不能包含username引數,但必須包含password引數,才能與當前標註的方法進行對映。
  3. @RequestMapping(value="/login", params={ "username=admin" , "password"}) 表示:請求引數中必須包含username引數,並且引數的值必須是admin,另外也必須包含password引數,才能與當前標註的方法進行對映。
  4. @RequestMapping(value="/login", params={ "username!=admin" , "password"}) 表示:請求引數中必須包含username引數,但引數的值不能是admin,另外也必須包含password引數,才能與當前標註的方法進行對映。

注意:如果前端提交的引數,和後端要求的請求引數不一致,則出現400錯誤!!!

HTTP狀態碼400的原因:請求引數格式不正確而導致的。

img

6.3. 測試params屬性

在 RequestMappingTestController 類中新增如下方法:

@RequestMapping(value="/testParams", params = {"username", "password"})
public String testParams(){
    return "testParams";
}

提供檢視頁面:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>testParams</title>
</head>
<body>
<h1>測試RequestMapping註解的Params屬性</h1>
</body>
</html>

在index.html檔案中新增超連結:

<!--測試RequestMapping的params屬性-->
<a th:href="@{/testParams(username='admin',password='123')}">測試params屬性</a>

當然,你也可以這樣寫:這樣寫IDEA會報錯,但不影響使用。

<a th:href="@{/testParams?username=admin&password=123}">測試params屬性</a><br>

啟動伺服器,測試:

img

img

img

假如傳送請求時,沒有傳遞username引數會怎樣?

<a th:href="@{/testParams(password='123')}">測試params屬性</a><br>

啟動伺服器,測試:

img

img

提示無效的請求引數,伺服器無法或不會處理當前請求。

params屬性剩下的三種情況,自行測試!!!!

7. RequestMapping註解的headers屬性

7.1. 認識headers屬性

headers和params原理相同,用法也相同。

當前端提交的請求頭資訊和後端要求的請求頭資訊一致時,才能對映成功。

請求頭資訊怎麼檢視?在chrome瀏覽器中,F12開啟控制檯,找到Network,可以檢視具體的請求協議和響應協議。在請求協議中可以看到請求頭資訊,例如:

img

請求頭資訊和請求引數資訊一樣,都是鍵值對形式,例如上圖中:

  • Referer: http://localhost:8080/springmvc/ 鍵是Referer,值是http://localhost:8080/springmvc/
  • Host: localhost:8080 鍵是Host,值是localhost:8080

7.2. headers屬性的4種用法

  1. @RequestMapping(value="/login", headers={ "Referer" , "Host"}) 表示:請求頭資訊中必須包含Referer和Host,才能與當前標註的方法進行對映。
  2. @RequestMapping(value="/login", headers={ "Referer" , "!Host"}) 表示:請求頭資訊中必須包含Referer,但不包含Host,才能與當前標註的方法進行對映。
  3. @RequestMapping(value="/login", headers={ "Referer=http://localhost:8080/springmvc/" , "Host"}) 表示:請求頭資訊中必須包含Referer和Host,並且Referer的值必須是http://localhost:8080/springmvc/,才能與當前標註的方法進行對映。
  4. @RequestMapping(value="/login", headers={ "Referer!=http://localhost:8080/springmvc/" , "Host"}) 表示:請求頭資訊中必須包含Referer和Host,並且Referer的值不是http://localhost:8080/springmvc/,才能與當前標註的方法進行對映。

注意:如果前端提交的請求頭資訊,和後端要求的請求頭資訊不一致,則出現404錯誤!!!

7.3. 測試headers屬性

在 RequestMappingTestController 類中新增以下方法:

@RequestMapping(value="/testHeaders", headers = {"Referer=http://localhost:8080/springmvc/"})
public String testHeaders(){
    return "testHeaders";
}

提供檢視頁面:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>test Headers</title>
</head>
<body>
<h1>測試RequestMapping註解的headers屬性</h1>
</body>
</html>

在index.html頁面中新增超連結:

<!--測試RequestMapping的headers屬性-->
<a th:href="@{/testHeaders}">測試headers屬性</a><br>

啟動伺服器,測試結果:

img

img

將後端控制器中的headers屬性值進行修改:

@RequestMapping(value="/testHeaders", headers = {"Referer=http://localhost:8888/springmvc/"})
public String testHeaders(){
    return "testHeaders";
}

再次測試:

img

其他情況自行測試!!!!

相關文章