1. RequestMapping的作用
@RequestMapping
註解是 Spring MVC 框架中的一個控制器對映註解,用於將請求對映到相應的處理方法上。具體來說,它可以將指定 URL 的請求繫結到一個特定的方法或類上,從而實現對請求的處理和響應。
2. RequestMapping的出現位置
透過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伺服器,會發現沒有再報錯了。
為這兩個請求分別提供對應的檢視頁面:
<!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/
點選使用者詳情,點選商品詳情,都可以正常顯示:
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";
}
}
經過測試,程式可以正常執行!!!
4. RequestMapping註解的value屬性
4.1. value屬性的使用
value屬性是該註解最核心的屬性,value屬性填寫的是請求路徑,也就是說透過該請求路徑與對應的控制器的方法繫結在一起。另外透過原始碼可以看到value屬性是一個字串陣列:
既然是陣列,就表示可以提供多個路徑,也就是說,在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>
啟動伺服器,測試,點選以下的兩個超連結,傳送請求,都可以正常訪問到同一個控制器上的同一個方法:
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>
測試結果如下:
透過修改瀏覽器位址列上的路徑,可以反覆測試萬用字元 ? 的語法:
將 ? 萬用字元修改為 * 萬用字元:
//@RequestMapping("/x?z/testValueAnt")
@RequestMapping("/x*z/testValueAnt")
public String testValueAnt(){
return "testValueAnt";
}
開啟瀏覽器直接在位址列上輸入路徑進行測試:
將 * 萬用字元修改為 ** 萬用字元:
@RequestMapping("/x**z/testValueAnt")
public String testValueAnt(){
return "testValueAnt";
}
注意:/x**z/ 實際上並沒有使用萬用字元 **,本質上還是使用的 *,因為萬用字元 ** 在使用的時候,左右兩邊都不能有任何字元,必須是 /。
@RequestMapping("/**/testValueAnt")
public String testValueAnt(){
return "testValueAnt";
}
啟動伺服器發現報錯了:
以上寫法在Spring5的時候是支援的,但是在Spring6中進行了嚴格的規定,** 萬用字元只能出現在路徑的末尾,例如:
@RequestMapping("/testValueAnt/**")
public String testValueAnt(){
return "testValueAnt";
}
測試結果:
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>
啟動伺服器測試:
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屬性也是一個陣列:
陣列中的每個元素是 RequestMethod,而RequestMethod是一個列舉型別的資料:
因此如果要求前端傳送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>
在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>
啟動伺服器,測試:
透過測試,前端傳送的請求方式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>
再次測試:
因此,可以看出,對於RequestMapping註解來說,多一個屬性,就相當於多了一個對映的條件,如果value和method屬性都有,則表示只有前端傳送的請求路徑 + 請求方式都滿足時才能與控制器上的方法建立對映關係,只要有一個不滿足,則無法建立對映關係。例如:@RequestMapping(value="/login", method = RequestMethod.POST) 表示當前端傳送的請求路徑是 /login,並且傳送請求的方式是POST的時候才會建立對映關係。如果前端傳送的是get請求,或者前端傳送的請求路徑不是 /login,則都是無法建立對映的。
5.2. 衍生Mapping
對於以上的程式來說,SpringMVC提供了另一個註解,使用這個註解更加的方便,它就是:PostMapping,使用該註解時,不需要指定method屬性,因為它預設採用的就是POST處理方式:修改RequestMappingTestController程式碼如下
//@RequestMapping(value="/login", method = RequestMethod.POST)
@PostMapping("/login")
public String testMethod(){
return "testMethod";
}
當前端傳送get請求時,測試一下:
當前端傳送post請求時,測試一下:
在SpringMVC中不僅提供了 PostMaping註解,像這樣的註解還有四個,包括:
- GetMapping:要求前端必須傳送get請求
- PutMapping:要求前端必須傳送put請求
- DeleteMapping:要求前端必須傳送delete請求
- PatchMapping:要求前端必須傳送patch請求
5.3. web的請求方式
前端向伺服器傳送請求的方式包括哪些?共9種,前5種常用,後面作為了解:
- GET:獲取資源,只允許讀取資料,不影響資料的狀態和功能。使用 URL 中傳遞引數或者在 HTTP 請求的頭部使用引數,伺服器返回請求的資源。
- POST:向伺服器提交資源,可能還會改變資料的狀態和功能。透過表單等方式提交請求體,伺服器接收請求體後,進行資料處理。
- PUT:更新資源,用於更新指定的資源上所有可編輯內容。透過請求體傳送需要被更新的全部內容,伺服器接收資料後,將被更新的資源進行替換或修改。
- DELETE:刪除資源,用於刪除指定的資源。將要被刪除的資源識別符號放在 URL 中或請求體中。
- HEAD:請求伺服器返回資源的頭部,與 GET 命令類似,但是所有返回的資訊都是頭部資訊,不能包含資料體。主要用於資源檢測和快取控制。
- PATCH:部分更改請求。當被請求的資源是可被更改的資源時,請求伺服器對該資源進行部分更新,即每次更新一部分。
- OPTIONS:請求獲得伺服器支援的請求方法型別,以及支援的請求頭標誌。“OPTIONS *”則返回支援全部方法型別的伺服器標誌。
- TRACE:伺服器響應輸出客戶端的 HTTP 請求,主要用於除錯和測試。
- CONNECT:建立網路連線,通常用於加密 SSL/TLS 連線。
注意:
- 使用超連結以及原生的form表單只能提交get和post請求,put、delete、head請求可以使用傳送ajax請求的方式來實現。
- 使用超連結傳送的是get請求
- 使用form表單,如果沒有設定method,傳送get請求
- 使用form表單,設定method="get",傳送get請求
- 使用form表單,設定method="post",傳送post請求
- 使用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";
}
測試結果:
透過測試得知,即使form中method設定為put方式,但仍然採用get方式傳送請求。
再次修改RequestMappingTestController:
@RequestMapping(value="/login", method = RequestMethod.GET)
//@PostMapping("/login")
public String testMethod(){
return "testMethod";
}
再次測試:
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. 區別是什麼
- get請求傳送資料的時候,資料會掛在URI的後面,並且在URI後面新增一個“?”,"?"後面是資料。這樣會導致傳送的資料回顯在瀏覽器的位址列上。
http://localhost:8080/springmvc/login?username=zhangsan&userpwd=1111
- post請求傳送資料的時候,在請求體當中傳送。不會回顯到瀏覽器的位址列上。也就是說post傳送的資料,在瀏覽器位址列上看不到。
- get請求只能傳送普通的字串。並且傳送的字串長度有限制,不同的瀏覽器限制不同。這個沒有明確的規範。get請求無法傳送大資料量。
- post請求可以傳送任何型別的資料,包括普通字串,流媒體等資訊:影片、聲音、圖片。post請求可以傳送大資料量,理論上沒有長度限制。
- get請求在W3C中是這樣說的:get請求比較適合從伺服器端獲取資料。
- post請求在W3C中是這樣說的:post請求比較適合向伺服器端傳送資料。
- get請求是安全的。因為在正確使用get請求的前提下,get請求只是為了從伺服器上獲取資料,不會對伺服器資料進行修改。
- post請求是危險的。因為post請求是修改伺服器端的資源。
- get請求支援快取。 也就是說當第二次傳送get請求時,會走瀏覽器上次的快取結果,不再真正的請求伺服器。(有時需要避免,怎麼避免:在get請求路徑後新增時間戳)
- post請求不支援快取。每一次傳送post請求都會真正的走伺服器。
5.4.2. 怎麼選擇
- 如果你是想從伺服器上獲取資源,建議使用GET請求,如果你這個請求是為了向伺服器提交資料,建議使用POST請求。
- 大部分的form表單提交,都是post方式,因為form表單中要填寫大量的資料,這些資料是收集使用者的資訊,一般是需要傳給伺服器,伺服器將這些資料儲存/修改等。
- 如果表單中有敏感資訊,建議使用post請求,因為get請求會回顯敏感資訊到瀏覽器位址列上。(例如:密碼資訊)
- 做檔案上傳,一定是post請求。要傳的資料不是普通文字。
- 其他情況大部分都是使用get請求。
6. RequestMapping註解的params屬性
6.1. params屬性的理解
params屬性用來設定透過請求引數來對映請求。
對於RequestMapping註解來說:
- value屬性是一個陣列,只要滿足陣列中的任意一個路徑,就能對映成功
- method屬性也是一個陣列,只要滿足陣列中任意一個請求方式,就能對映成功。
- params屬性也是一個陣列,不過要求請求引數必須和params陣列中要求的所有引數完全一致後,才能對映成功。
6.2. params屬性的4種用法
- @RequestMapping(value="/login", params={ "username" , "password"}) 表示:請求引數中必須包含 username 和 password,才能與當前標註的方法進行對映。
- @RequestMapping(value="/login", params={ "!username" , "password"}) 表示:請求引數中不能包含username引數,但必須包含password引數,才能與當前標註的方法進行對映。
- @RequestMapping(value="/login", params={ "username=admin" , "password"}) 表示:請求引數中必須包含username引數,並且引數的值必須是admin,另外也必須包含password引數,才能與當前標註的方法進行對映。
- @RequestMapping(value="/login", params={ "username!=admin" , "password"}) 表示:請求引數中必須包含username引數,但引數的值不能是admin,另外也必須包含password引數,才能與當前標註的方法進行對映。
注意:如果前端提交的引數,和後端要求的請求引數不一致,則出現400錯誤!!!
HTTP狀態碼400的原因:請求引數格式不正確而導致的。
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>
啟動伺服器,測試:
假如傳送請求時,沒有傳遞username引數會怎樣?
<a th:href="@{/testParams(password='123')}">測試params屬性</a><br>
啟動伺服器,測試:
提示無效的請求引數,伺服器無法或不會處理當前請求。
params屬性剩下的三種情況,自行測試!!!!
7. RequestMapping註解的headers屬性
7.1. 認識headers屬性
headers和params原理相同,用法也相同。
當前端提交的請求頭資訊和後端要求的請求頭資訊一致時,才能對映成功。
請求頭資訊怎麼檢視?在chrome瀏覽器中,F12開啟控制檯,找到Network,可以檢視具體的請求協議和響應協議。在請求協議中可以看到請求頭資訊,例如:
請求頭資訊和請求引數資訊一樣,都是鍵值對形式,例如上圖中:
- Referer: http://localhost:8080/springmvc/ 鍵是Referer,值是http://localhost:8080/springmvc/
- Host: localhost:8080 鍵是Host,值是localhost:8080
7.2. headers屬性的4種用法
- @RequestMapping(value="/login", headers={ "Referer" , "Host"}) 表示:請求頭資訊中必須包含Referer和Host,才能與當前標註的方法進行對映。
- @RequestMapping(value="/login", headers={ "Referer" , "!Host"}) 表示:請求頭資訊中必須包含Referer,但不包含Host,才能與當前標註的方法進行對映。
- @RequestMapping(value="/login", headers={ "Referer=http://localhost:8080/springmvc/" , "Host"}) 表示:請求頭資訊中必須包含Referer和Host,並且Referer的值必須是http://localhost:8080/springmvc/,才能與當前標註的方法進行對映。
- @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>
啟動伺服器,測試結果:
將後端控制器中的headers屬性值進行修改:
@RequestMapping(value="/testHeaders", headers = {"Referer=http://localhost:8888/springmvc/"})
public String testHeaders(){
return "testHeaders";
}
再次測試:
其他情況自行測試!!!!