SpringMVC中的@RequestMapping注解的使用詳細教程
@RequestMapping注解的功能
從注解名稱上我們可以看出,@RequestMapping注解的作用就是將請求和處理請求的控制器方法關聯(lián)起來
,建立映射關系,SpringMVC接收到指定的請求,就會來找到在映射關系中對應的控制方法來處理這個請求。
@RequestMapping注解的位置
@RequestMapping標識一個類
:設置映射請求的請求路徑的初始信息
@RequestMapping標識一個方法
:設置映射請求,請求路徑的具體信息
如下所示:
當前我們Protal方法的訪問路徑是hello
package AnnotationController; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class ProtalController { @RequestMapping("/hello") public String Protal(){ return "index"; } }
當前的控制層,我們只給控制層中的Protal方法加上了@RequestMapping注解,而并沒有給該控制層的類上加,因此我們可以直接通過Protal方法上的請求路徑訪問。
假設我們此時也給類加上@RequestMapping注解,訪問地址不變化,如下所示:
@RequestMapping("test") public class ProtalController {
訪問結果如下所示,我們會發(fā)現(xiàn)當前資源無法被找到
要想資源 被正確的訪問,我們需要進行如下操作:
在路徑的具體信息之前添加路徑的初始信息,因為當在類上添加了請求路徑的初始信息之后,我們想訪問該類中的某個方法,就必須先正確的訪問到該類。
而這樣做的目的在于,在實際開發(fā)中,我們往往會給請求方法設置較為簡單的路徑請求具體信息,例如查詢學生的方法,我們會將其請求路徑具體的信息設置select,刪除學生的方法,我們會將其我們會將其請求路徑具體的信息設置delete,而需求往往不是適合于一類人而已,對于除學生以外的其他用戶,都會有增刪的操作,這樣就導致了,系統(tǒng)也不知道該訪問哪一個,因此,我們需要在類上添加請求路徑的初始化信息。
@RequestMapping注解value屬性值
我們通過查看@RequestMapping注解:
它的匹配方式有很多種,通過請求路徑,通過請求方法…,而比較常用的就是通過path和method
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) // package org.springframework.web.bind.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.core.annotation.AliasFor; @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Mapping public @interface RequestMapping { String name() default ""; @AliasFor("path") String[] value() default {}; @AliasFor("value") String[] path() default {}; RequestMethod[] method() default {}; String[] params() default {}; String[] headers() default {}; String[] consumes() default {}; String[] produces() default {}; }
@RequestMapping注解value屬性
通過查看源碼可知,value的類型為String[],如下所示:
我們將@RequestMapping的值設置為多個
package AnnotationController; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class ProtalController { //當匹配方式中只有value時,value可以省略不寫 @RequestMapping({"/hello","/abc"}) public String Protal(){ return "index"; } }
那么我們是否可以根據(jù)數(shù)組中任意的一個值來訪問到正確的資源呢?
我們將項目重新部署:
由此可知,@RequestMapping注解value屬性的作用是
:通過請求的請求路徑匹配請求
,value屬性是數(shù)組類型
,即當前瀏覽器所發(fā)送請求的請求路徑匹配value屬性中的任何一個值,則當前請求就會被注解所標識的方法進行處理
@RequestMapping注解method屬性
通過查看源碼如下所示,我們知道m(xù)ethod屬性是ReuestMethod類型的:
RequestMethod[] method() default {<!-- -->};
繼續(xù)跟進查看ReuestMethod的源碼,如下所示:
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) // package org.springframework.web.bind.annotation; public enum RequestMethod { GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE; private RequestMethod() { } }
我們發(fā)現(xiàn)它是一個枚舉類型,列舉了所有的請求方式,其中get和post是我們已經(jīng)學過的,那么接下來我們就以post和get請求為例演示起作用。
創(chuàng)建實現(xiàn)頁面跳轉的模塊
首頁請求控制器:
package AnnotationController; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class ProtalController { @RequestMapping("/") public String Protal(){ return "index"; } }
跳轉頁面請求控制器
package AnnotationController; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class JumpPageController { @RequestMapping(value = {"/hello","/abc"},method= RequestMethod.GET) public String Page(){ return "success"; } }
index.html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>首頁</title> </head> <body> <h1>成功進入首頁!</h1> <a th:href="@{/hello}">測試@RequestMapping注解所標識的位置</a><br> <a th:href="@{/abc}">測試@RequestMapping注解的value屬性</a><br> <form th:action="@{/hello}"> <input type="submit" value="測試@RequestMapping注解的method屬性"> </form> </body> </html>
success.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>
此時運行服務器,如下所示:
點擊其中的任何一個連接,都會出現(xiàn)如下字樣:
通過輸出結果,我們不難發(fā)現(xiàn)將@RequestMapping注解中的method屬性值設置為RequestMethod.GET,也就是匹配get請求的方式是沒有任何問題的,那么如果我們將其匹配的是post還會如此嗎?
修改@RequestMapping注解中的method屬性值為RequestMethod.POST,再次運行:
出現(xiàn)下述異常:
tomcat告訴我們是因為方法不被支持
那為什么當我們將將@RequestMapping注解中的method屬性值設置為RequestMethod.GET就能正確的處理請求?原因是:無論是超鏈接還是表單,默認的提交方式都是get請求,因此當我們沒有設置其值的情況情況下,默認的就是get請求方式
我們可以將表單的提交方式設置為POST,這樣就可以處理POST請求了:
<form th:action="@{/hello}" method="post"> <input type="submit" value="測試@RequestMapping注解的method屬性"> </form>
如下所示,通過method屬性,將其表單提交的方式設置為post
此時點擊該按鈕就可以成功的進入success.html頁面啦
但是需要注意的是,如果我們把當前可以訪問成功的地址復制,直接在瀏覽器中訪問,如下所示:
還是出現(xiàn)了405錯誤,原因是我們將地址復制直接通過地址欄訪問,實際上是get請求,但是我們又在注解中將其請求方法設置為post請求,由于未能匹配,所以出現(xiàn)了405錯誤
通過查看它的源碼,我們得知其method是一個數(shù)組類型的,那么我們就可以利用這一特性,讓它既能匹配get請求,又能匹配post請求,設置如下所示:
@RequestMapping(value = {"/hello","/abc"},method= {RequestMethod.POST,RequestMethod.GET})
此時我們刷新剛剛復制地址,而導致報錯的頁面,就能成功訪問啦,只要是get、post中的任意一個都能被成功訪問
@RequestMapping注解的method屬性
的作用是通過請求的請求方式匹配請求,它RequestMethod類型的數(shù)組
,即當前瀏覽器所發(fā)送請求的請求方式匹配method屬性中的任何一個請求,如果匹配成功,那么當前請求就會被注解所標識的方法進行處理,若瀏覽器所發(fā)送的請求的請求路徑和@RequestMapping注解value屬性匹配,但是請求方式不匹配,頁面會報錯,如下所示:
在@ResquestMapping的基礎上,結合請求方式的一些派生注解:
@GetMapping,@PostMapping,@DeleteMapping,@PutMapping,關于這些注解在后續(xù)的學習中會使用。
@RequestMapping注解params屬性
String[] params() default {<!-- -->};
@RequestMapping注解params屬性的作用是通過請求的請求參數(shù)匹配請求,即瀏覽器發(fā)送的請求的請求參數(shù)必須滿足params屬性的設置
,params可以使用四種表達式:
“param”:表示當前所匹配請求的請求參數(shù)中必須攜帶param參數(shù)
測試如下所示:
在注解中,我們添加param屬性,并給定一個值為username
package AnnotationController; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller public class JumpPageController { @RequestMapping(value = {"/hello","/abc"}, method= {RequestMethod.POST,RequestMethod.GET} ,params = {"username"}) public String Page(){ return "success"; } }
再重新進行項目的部署,點擊超鏈接或者表單中的按鈕,出現(xiàn)以下錯誤:
原因是,我們在注解中設置了其參數(shù)的值,而在地址欄中并沒有該參數(shù)的值,所以會報錯。
解決方法如下所示:
<!--以下兩種方式毫無區(qū)別,唯一的區(qū)別是第一種寫法在源文件中會報錯,但是該報錯不影響代碼的編譯和執(zhí)行 --> <a th:href="@{/hello?username=admin}" >測試@RequestMapping注解的param屬性</a><br> <a th:href="@{/hello(username='admin')}" >測試@RequestMapping注解的param屬性</a>
通過這種方式,瀏覽器會在地址欄自動為我們添加其值,如下所示:
此時頁面也能被成功的訪問到!
但需要注意的是,param屬性和method屬性以及value屬性可不一樣哦,當我們將method屬性和value屬性中設置有多個值時,只要能匹配到其中的任意一個即可,但是對于param屬性來說,如果設置的值有多個必須同時匹配,測試如下:
給param屬性值增加password,其他地方不做任何的變動
@RequestMapping(value = {"/hello","/abc"}, method= {RequestMethod.POST,RequestMethod.GET} ,params = {"username","password"})
測試結果如下所示:
此時報錯原因依然為在注解中設置了Parma屬性值password,但是未能匹配到該值,所以出現(xiàn)錯誤,解決方法有兩種,一種是我們在html文件中設置該參數(shù),由瀏覽器自動為我們匹配,如下所示:
index.html:
<a th:href="@{/hello(username=${admin},password=${1234})}" >測試@RequestMapping注解的param屬性</a> <a th:href="@{/hello(username='admin',password='12345')}">測試@RequestMapping注解的param屬性</a>
重新部署項目,運行如下所示:
第二種方式是我們在地址欄通過手動添加缺失的參數(shù),如下所示:
也可以成功進入到我們想訪問的頁面!
“!param”:表示當前所匹配請求的請求參數(shù)中一定不能攜帶param參數(shù)
假設此時我們將注解修改如下所示:
請求參數(shù)中不可以包含password,即使是只有password這個參數(shù),沒有值也不可以。
@RequestMapping(value = {"/hello","/abc"}, method= {RequestMethod.POST,RequestMethod.GET} ,params = {"username","!password"})
重新部署項目如下所示,我們手動在地址欄添加了password,雖然只是添加了該參數(shù)沒有給定具體的值,結果也報錯了。
“param=value”:表示當前所匹配請求的請求參數(shù)中必須攜帶param參數(shù)且值必須為value
假設此時我們將注解修改如下所示:
添加請求參數(shù),并將其值設置為20
@RequestMapping(value = {"/hello","/abc"}, method= {RequestMethod.POST,RequestMethod.GET} ,params = {"username","!password","age=20"})
重新部署項目,如下所示,只有當注解中的設置的所有請求參數(shù)都被滿足時,該請求才能被正確處理
“param!=value”:表示當前所匹配請求的請求參數(shù)中可以不攜帶param,若攜帶值一定不能是value
假設此時我們將注解修改如下所示:
添加新的請求參數(shù)gender,并設置其值不能為男
@RequestMapping(value = {"/hello","/abc"}, method= {RequestMethod.POST,RequestMethod.GET} ,params = {"username","!password","age=20","gender!=男"})
重新部署項目,測試如下所示:
手動添加其參數(shù)的值,gender的值可以是除了男以外的任何值,當然也可以不傳值,或者不手動在地址欄添加該請求參數(shù)均可
@RequestMapping注解headers屬性
String[] headers() default {<!-- -->};
@RequestMapping注解的headers屬性
通過請求的請求頭信息匹配請求映射,它是一個字符串類型的數(shù)組,可以通過四種表達式設置請求頭信息和請求映射的匹配關系,如下所示:
"header"
:要求請求映射所匹配的請求必須攜帶header請求頭信息
"!header"
:要求請求映射所匹配的請求必須不能攜帶header請求頭信息
"header=value"
:要求請求映射所匹配的請求必須攜帶header請求頭信息且header=value
"header!=value"
:要求請求映射所匹配的請求必須攜帶header請求頭信息且header!=value
若當前請求滿足@RequestMapping注解的value和method屬性,但是不滿足headers屬性
,此時頁面顯示404錯誤
,即資源未找到
例如:我們可以通過設置headers的referer屬性來指明當前資源的來源地址,如下所示:
@RequestMapping(value = {"/hello","/abc"}, method= {RequestMethod.POST,RequestMethod.GET},headers = {"referer"})
重新部署項目,在瀏覽器中右擊打開檢查,如下所示為我們?yōu)辄c擊該超鏈接的請求頭信息:
此時我們點擊該超鏈接,如下圖所示,與上圖不同之處在于多了一個Referer屬性,而該屬性的值即為該頁面的來源地址
注意:響應頭和請求頭中的鍵不區(qū)分大小寫,但是其鍵值區(qū)分大小寫
@RequestMapping注解使用ant風格的路徑
?:表示任意的單個字符
舉例如下:
**第一步:**編寫新的測試方法,并將其RequestMapping的值設置為/a?a/test/ant
package AnnotationController; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class JumpPageController { @RequestMapping("/a?a/test/ant") public String testAnt(){ return "success"; } }
第二步:在index.html中為其添加超鏈接
<a th:href="@{/aaa/test/ant}">測試@RequestMapping注解支持ant風格的路徑</a><br>
將項目重新部署,測試結果如下:
點擊該超鏈接:
通過我們在index.html文件中設置的路徑,此時資源被正確的訪問到,既然?是代表一個任意的字符,那么我們可以將a和a中鍵的位置任意選擇一個符號來代替,可以是數(shù)字,可以是其他字母,當然也可以是特殊字符,但是需要注意不能是英文的問號,中文的問號是可以的,否則如下所示:
原因是**?前面是請求路徑,問號后面是請求參數(shù)**,/a?a/test/ant并不會被當做一個完整的請求路徑,其替代?的字符也不能是/,因為它代表地址的分隔符,表示新的一層目錄
*:表示任意的0個或多個字符
舉例如下:
此時我們將上述注解中的?替換為*,如下所示:
@RequestMapping("/a*a/test/ant")
將項目重新部署后,刷新瀏覽器頁面如下所示:
無論是一個字符還是多個字符,都能成功的訪問地址
而需要注意的是和?占位符相同,此時替代*的字符不可以是/或者?(英文),否則會出現(xiàn)404,原因和?的是相通的
**:表示任意層數(shù)的任意目錄
舉例如下:
將路徑中的具體信息修改為如下所示:
@RequestMapping("/**/test/ant")
需要注意的是**只能寫在//中,前后都不能有任何的字符
。
錯誤實例:
@RequestMapping("/a**a/test/ant") @RequestMapping("/**a/test/ant")
重新部署項目,測試結果如下所示:
/**/所代表的的目錄我們既可以設置為一層,也可以設置為多層
但需要注意的是,即使可以設置任意層,但是目錄中依然不可以包含有英文的問號,否則如下所示:
注意:在使用**
時,只能使用/**/xxx
的方式
@RequestMapping注解使用路徑中的占位符
通過路徑傳值的傳統(tǒng)方式為:
/deleteUser?id=1
下面我們要介紹一種簡單的方式:需要在@RequestMapping注解的value屬性中所設置的路徑中,使用{xxx}的方式表示路徑中的數(shù)據(jù),在通過@PathVariable注解,將占位符所標識的值和控制器方法的形參進行綁定,具體操作如下所示:
第一步:編寫對應的控制器方法
package AnnotationController; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class JumpPageController { //注意:有幾個參數(shù)需要寫幾個{xxx}{xxx} @RequestMapping("/test/rest/{username}/{id}") //@PathVariable注解的值必須與@RequestMapping注解路徑具體信息中的參數(shù)名稱相一致,否則會出現(xiàn)500錯誤 public String testRest(@PathVariable("id") Integer id,@PathVariable("username") String username){ //獲取對應參數(shù)的值 System.out.println("id:"+id+","+"username:"+username); return "success"; } }
第二步:在index.html文件中,設置其參數(shù)的具體值
注意這里值的順序應與@RequestMapping注解中的參數(shù)順序保持一致,否則會因為類型不匹配導致出現(xiàn)400錯誤
<a th:href="@{/test/rest/admin/1}">測試@RequestMapping注解value屬性中的占位符</a><br>
重新部署項目,測試結果如下:
在瀏覽器欄顯示了其參數(shù)的值
在控制臺,也將對應的參數(shù)信息顯示出來了
以上就是SpringMVC中的@RequestMapping注解的使用詳細教程的詳細內(nèi)容,更多關于SpringMVC @RequestMapping注解的資料請關注腳本之家其它相關文章!
相關文章
SpringBoot中EasyExcel實現(xiàn)Excel文件的導入導出
這篇文章主要介紹了SpringBoot中EasyExcel實現(xiàn)Excel文件的導入導出,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-10-10JAVA 統(tǒng)計字符串中中文,英文,數(shù)字,空格,特殊字符的個數(shù)
這篇文章主要介紹了JAVA 統(tǒng)計字符串中中文,英文,數(shù)字,空格,特殊字符的個數(shù) ,本文通過一段代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-06-06FeignClient如何通過配置變量調(diào)用配置文件url
這篇文章主要介紹了FeignClient如何通過配置變量調(diào)用配置文件url,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06