一篇文章搞定springMVC中的請求對映
實驗的專案是採用預設配置的spring boot專案,使用的工具為IDEA和POSTMAN。
希望這些案例能夠幫助你理解和思考。
talk is cheap,show me the code!
1、從最簡單的hello world開始
@Controller
public class HelloController {
@RequestMapping("/helloWorld")
@ResponseBody
public String helloWorld(){
return "hello world";
}
}
上例也許就是一個最簡單的springmvc程式碼了,當請求的uri為”/helloWorld”時,將會得到字串”hello world”,下圖是用postman模擬請求的結果。
簡單介紹幾個基礎的註解,因為後面的實驗中可能會用到:
- @Controller 宣告HelloController類為springMVC中的一個controller,優點是不需要繼承任何類或者實現任何的介面。在配置了註解掃描後,頭上有@Controller註解的類將會被spring容器自動的載入。
spring 註解掃描的配置方式(java config)如下:
@Configuration
@ComponentScan("org.example.web")
public class WebConfig {
// ...
}
- @RequestMapping: 用於提供的請求對映資訊。@RequestMapping註解即可以用在class級別中也可以用在方法級別中。
- @ResponseBody: 表示該方法的返回結果直接寫入 HTTP response body 中。
- @GetMapping、@PostMapping、@PutMapping等:他們相當於RequestMapping(value = “/xxx” , method = RequestMethod.GET)或 RequestMapping(value = “/xxx” , method = RequestMethod.POST),即限定請求方法的簡寫。
- @RestController :官方文件的描述如下,即@RestController 註解相當於@Controller和@ResponseBody兩個註解的組合。
@RestController is a composed annotation that is itself annotated with @Controller and @ResponseBody
2、通過指定HTTP請求方法來限定請求
URI為”/testShortcut”的介面將請求的方法限定為GET請求,也就以為著請求地址和請求方法都必須正確才會返回字串”success”。
程式碼如下:
@Controller
public class MyRequestMappingDemo {
@RequestMapping(value = "/testShortcut",method = RequestMethod.GET)
@ResponseBody
public String testShortcut(){
return "success";
}
}
使用postman請求介面”/testShortcut”如下,可以看到,使用的HTTP METHOD為GET請求,並且成功返回了字串”success”。
下面使用HTTP METHOD為POST請求同樣的介面
可以看到,同樣的介面只是請求的方式不同得到的結果也就不相同。達到了通過請求方式來限定請求的目的。
再此順便試一下@GetMapping、@PostMapping、@PutMapping等註解好不好用。
@Controller
public class GETMappingDemo {
@GetMapping(value= "/testGetMapping")
@ResponseBody
public String testGetMapping(){
return "testGetMapping";
}
}
由上面兩張圖可以看到,@GetMapping、@PostMapping等註解對於通過請求方式來限定也是賊好用的。
3、url pattern
springMVC也是支援在請求的url中使用萬用字元的,具體規則如下:- ?萬用字元表示匹配一個字元(matches one character)。
- 萬用字元表示在一個路徑分段中匹配一個或者多個字元(matches zero or more characters within a path segment)。
- ** 統配符表示匹配零個或者多個路徑分段(match zero or more path segments)。
相關程式碼和實驗如下:
@RestController
public class URIPatternsDemo {
@RequestMapping("/testURIPatterns/?")
public String testURIPatterns(){
return "?萬用字元表示匹配一個字元!";
}
@RequestMapping("/testURIPatterns1/*")
public String testURIPatterns1(){
return "*萬用字元表示匹配零個或者多個字元,但必須是在一個路徑分段中!";
}
@RequestMapping("/testURIPatterns2/**")
public String testURIPatterns2(){
return "**萬用字元表示匹配零個或者多個路徑分段!";
}
}
上述程式碼中,URIPatternsDemo類裡定義了三個方法,分別用於測試三種萬用字元的使用。使用postman測試如下:
1、測試?萬用字元,路徑中輸入一個字元a,資訊成功返回。
2、測試?萬用字元,路徑中輸入一個字元b,資訊成功返回。
3、測試?萬用字元,路徑中輸入多個字元,報錯。
結論,?萬用字元只能匹配一個隨機的字元
4、測試*萬用字元,路徑中輸入多個字元,正確返回。
5、測試*萬用字元,路徑中輸入零個字元,正確返回。
6、測試*萬用字元,在多個路徑分段中輸入多個字元,報錯。
結論,* 萬用字元表示在一個路徑分段中匹配一個或者多個字元
7、測試**萬用字元,在一個路徑分段中輸入多個字元,正確返回。
8、測試**萬用字元,在多個路徑分段中輸入多個字元,正確返回。
8、測試**萬用字元,零個路徑分段,正確返回。
結論,** 統配符表示匹配零個或者多個路徑分段。
4、URI Template Patterns
URI templates can be used for convenient access to selected parts of a URL in a @RequestMapping method.
URI模板可以很方便的用於獲取@RequestMapping方法裡的URL的一部分。(本屌的渣渣翻譯)
意思就是說可以使用URI Template獲取URL路徑中的變數。在sprngMVC中使用的是@PathVariable註解。talk is cheap,上程式碼。
@Controller
public class TestUrlPatterns {
//演示一個URL路徑變數的情況
@RequestMapping("/UrlPatternDemo/{pathVar}")
@ResponseBody
public String UrlPatternDemo(@PathVariable String pathVar){
return pathVar;
}
//演示兩個路徑變數的情況
@RequestMapping("/multiUrlPatternDemo/{pathVar1}/{pathVar2}")
@ResponseBody
public String multiUrlPatternDemo(@PathVariable String pathVar1 , @PathVariable String pathVar2){
return "this is first path variable:" + pathVar1+", this is second path variable:" + pathVar2;
}
//演示路徑變數支援多種基本資料型別,而不是隻有String一種
@RequestMapping("/multiUrlPatternDemo2/{pathVar1}/{pathVar2}")
@ResponseBody
public String multiUrlPatternDemo2(@PathVariable Integer pathVar1 , @PathVariable Integer pathVar2){
return "第一個引數是:" + pathVar1+",第二個引數是:" + pathVar2 +"。兩個引數的和是:"+ (pathVar1 + pathVar2);
}
}
下面測試一下這三個方法:
結論:@PathVariable註解可以獲取請求URL中的路徑引數,並且也可以用基本資料型別來接收引數的值。
下面來討論一些特殊情況:
如果一個請求的URL同時匹配了多個萬用字元怎麼辦?
springMVC中有一些規則用於處理這種特殊情況,規則是:
- 例如,
/hotel/{hotel}/*
和/hotel/{hotel}/**
,前者具有一個路徑變數和一個萬用字元,而後者同樣是具有一個路徑變數,但是後者卻有兩個萬用字元。此時,springMVC認為前者更加的明確,所以前者的優先順序會更高一些。 /foo/bar*
和/foo/*
springMVC認為前者的指向更加明確,所以前者的優先順序更高。/hotels/{hotel}
和/hotels/*
springMVC認為前者的指向更加明確,原因是前者沒有用到萬用字元。/**
在springMVC中被認為是優先順序最低的。具體的規則在AntPathMatcher類的AntPatternComparator()方法中有完整的體現。
URI Template另外還有兩種用法,即與正則表示式一起使用和與Placeholders一起使用。
第一種:與正則一起使用
@RestController
public class RegexExpressionDemo {
@RequestMapping("/testRegexExpressionPattern/{name:[a-z-]+}")
public String testRegexExpressionPattern(@PathVariable String name){
return "正則表示式匹配的變數為:" + name;
}
}
第二種,與Placeholders一起使用
@Controller
@RequestMapping(value="${demo.path.variable}")
public class PropertiesPlaceholderDemo {
@RequestMapping("/testPropertiesPlaceholder")
@ResponseBody
public String testPropertiesPlaceholder(){
return "asd";
}
}
如上面程式碼所示,@RequestMapping註解中的引數來自properties配置檔案,當路徑正確匹配時,將會返回字串”asd”。所以我們在properties檔案中建立一個key為demo.path.variable的屬性。在這裡就直接寫在application.properties中,如下圖所示。
所以我們訪問的路徑應該為”/haha/testPropertiesPlaceholder”,下面為測試:
成功返回字串“asd”。
5、Matrix Variables
Matrix Variables意味矩陣變數,說白了就是名值對。解釋名詞是很蛋疼的事,直接上程式碼和實驗結果,對著程式碼和結果進行解釋。
要使用矩陣變數,首先需要將RequestMappingHandlerMapping類中的removeSemicolonContent屬性設為false,預設情況下為true。設定的方法也很簡單,下面是通過java config的方式配置該屬性。
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
UrlPathHelper urlPathHelper = new UrlPathHelper();
urlPathHelper.setRemoveSemicolonContent(false);
configurer.setUrlPathHelper(urlPathHelper);
}
}
實驗程式碼如下:
完整程式碼如下,其中有個沒見過的註解@MatrixVariable,下面通過實驗結果來說說這個註解到底是幹什麼。
@RestController
public class MatrixVariablesDemo {
@RequestMapping("/testMatrixVariables/{pathVar1}")
public String testMatrixVariables(@PathVariable String pathVar1,@MatrixVariable int matrixVariable1,@MatrixVariable int matrixVariable2){
return "pathVar1的值為:" + pathVar1 + "; matrixVariable1的值為:" + matrixVariable1 + "; matrixVariable2的值為:" + matrixVariable2;
}
@RequestMapping("/testMatrixVariables2/{pathVar1}/{pathVar2}")
public String testMatrixVariables2(@MatrixVariable(name = "matrixVariable",pathVar = "pathVar1") int matrixVariable1,@MatrixVariable(name = "matrixVariable",pathVar = "pathVar2") int matrixVariable2){
return " pathVar1變數中的matrixVariable的值為:" + matrixVariable1 + "; pathVar2變數中的matrixVariable的值為:" + matrixVariable2;
}
@RequestMapping("/testMatrixVariables3/{pathVar}")
public String testMatrixVariables3(@PathVariable String pathVar,@MatrixVariable(name = "matrixVariable",pathVar = "pathVar",required = false,defaultValue = "222233" ) String matrixVariable){
return "pathVar變數的值是:"+pathVar+",matrixVariable變數什麼值也沒傳,預設值是:" + matrixVariable;
}
@RequestMapping("/testMatrixVariables4/{pathVar1}/{pathVar2}")
public String testMatrixVariables4(@MatrixVariable MultiValueMap<String,String> matrixMap){
return matrixMap.toString();
}
@RequestMapping("/testMatrixVariables5/{pathVar1}/{pathVar2}")
public String testMatrixVariables5(@MatrixVariable(pathVar = "pathVar1") MultiValueMap<String,String> matrixMap){
return matrixMap.toString();
}
}
1、測試第一個介面“/testMatrixVariables/{pathVar1}”,實驗中請求的URL為http://localhost:8080//testMatrixVariables/20;matrixVariable1=1;matrixVariable2=2
結果如下:
先觀察URL,在{pathVar1}中有三個用分號分隔的部分,分別為20、matrixVariable1=1和matrixVariable2=2。回想Matrix Variable矩陣變數的定義,說它是明值對。這是可以大概明白所謂的矩陣變數就是寫在路徑變數{pathVar1}中的用分號“;”隔開的name=value對,即本例中的matrixVariable1=1和matrixVariable2=2。結合程式碼和實驗結果可知,@MatrixVariable註解的作用就是用來獲取路徑變數中的矩陣的變數的,並且可以用基本資料型別來接收。
2、測試第二個介面,URLhttp://localhost:8080//testMatrixVariables2/matrixVariable=1/matrixVariable=2
,結合程式碼可知,我們可以用@MatrixVariable註解,並通過指定pathVar屬性來獲取兩個不同路徑變數中同名的矩陣變數。
3、第三個介面用於測試@MatrixVariable註解的預設值,URLhttp://localhost:8080//testMatrixVariables3/1
,結果為:
4、第四個和第五個介面都是用於測試@MatrixVariable註解中用Map接收引數,URL分別為http://localhost:8080/testMatrixVariables4/a=a;b=b;c=c/a=aa;b=bb
和
http://localhost:8080/testMatrixVariables5/a=a;b=b;c=c/a=aa;b=bb
結果分別如下:
獲取所有路徑段中的矩陣變數,並用Map接收
指定獲取某個路徑分段中的矩陣變數,並用Map接收
6、通過限定MediaTypes、Request Parameters和Header Values來限制請求
通過Consumes,Produces註解來限定MediaTypes
consumes:指定處理請求的提交內容型別(Content-Type)。
produces:指定返回的內容型別,僅當request請求頭中的(Accept)型別中包含該指定型別才返回。
@Controller
@RequestMapping(value="/test")
public class ConsumableMediaTypesDemo {
@RequestMapping(value="/testConsumableMediaTypes",consumes = "application/json")
public String testConsumableMediaTypes(){
return "請求成功!";
}
@RequestMapping(value="/testConsumableMediaTypes1",consumes = MediaType.APPLICATION_JSON_VALUE)
public String testConsumableMediaTypes1(){
return "請求成功! MediaType.APPLICATION_JSON_VALUE";
}
@RequestMapping(value="/testConsumableMediaTypes2",consumes = MediaType.APPLICATION_XML_VALUE)
@ResponseBody
public String testConsumableMediaTypes2(){
return "請求成功! MediaType.APPLICATION_XML_VALUE";
}
}
1、第一個介面是用consumes屬性來限定MediaTypes的型別,並使用了字面量的形式限定型別,後面兩個介面使用了MediaType類中定義的常量。實驗的結果如下:
介面1:
介面2:
介面3:
produces、params和headers的使用方式與@Consumes相同
程式碼如下
@Controller
public class ProducibleMediaTypesDemo {
@RequestMapping(value = "/testProducibleMediaTypes",produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public String testProducibleMediaTypes(){
return "請求成功";
}
}
相關推薦
一篇文章搞定springMVC中的請求對映
實驗的專案是採用預設配置的spring boot專案,使用的工具為IDEA和POSTMAN。 希望這些案例能夠幫助你理解和思考。 talk is cheap,show me the code! 1、從最簡單的hello world開始 @
一篇文章搞定面試中的連結串列題目(java實現)
連結串列的資料結構 class ListNode { ListNode next; int val; ListNode(int x){ val = x; next = null;
一篇文章搞定SpringMVC參數綁定
進行 pwd dad 技術 默認 int acra servlet key SpringMVC參數綁定,簡單來說就是將客戶端請求的key/value數據綁定到controller方法的形參上,然後就可以在controller中使用該參數了 下面通過5個常用的註解演
一篇文章搞定面試中的二叉樹題目(java實現)
結構 cer dea mat lastcomm ++ mir let balanced 最近總結了一些數據結構和算法相關的題目,這是第一篇文章,關於二叉樹的。 先上二叉樹的數據結構: class TreeNode{ int val; //左孩子 Tr
一篇文章搞定——JDK8中新增的StampedLock
一、StampedLock類簡介 StampedLock類,在JDK1.8時引入,是對讀寫鎖ReentrantReadWrit
一篇文章搞定Markdown
markdown一篇文章搞定Markdown一篇文章搞定Markdown
一篇文章搞定前端面試
ron miss 就是 節點數 網頁 那是 png html 性能優化 本文旨在用最通俗的語言講述最枯燥的基本知識 面試過前端的老鐵都知道,對於前端,面試官喜歡一開始先問些HTML5新增元素啊特性啊,或者是js閉包啊原型啊,或者是css垂直水平居中怎麽實現啊之類的基礎問題
一篇文章搞定你的spring定時器
Cron表示式是一個字串,字串以5或6個空格隔開,分開工6或7個域,每一個域代表一個含義,Cron有如下兩種語法 格式: Seconds Minutes Hours DayofMonth Month DayofWeek Year 或 Seconds Minutes Hours DayofMo
面試專欄|一篇文章搞定ArrayList和LinkedList所有面試問題
在面試中經常碰到:ArrayList和LinkedList的特點和區別? 個人認為這個問題的回答應該分成這幾部分: 介紹ArrayList底層實現 介紹LinkedList底層實現 兩者個適用於哪些場合 本文也是按照上面這幾部分組織的。 ArrayList的原始碼解析
一篇文章搞定C語言所有的基本語法.
C 作為一門工程實用性極強的語言,提供了對作業系統和記憶體的精準控制,高效能的執行時環境,原始碼級的跨平臺編譯等優點,才是我們必須學習和使用 C 的理由。 C語言標記/令牌 C語言程式包括各種令牌和令牌可以是一個關鍵字,識別符號,常量,字串文字或符號。 例如,下面的C語句包括五個
一篇文章搞定Maven安裝到建立maven版Spring MVC專案及配置
配置maven 本地安裝 新建變數名為MAVEN_HOME,值為maven安裝目錄的系統變數 在系統變數名為Path的值中新增“%MAVEN_HOME%\bin;” cmd命令列輸入mvn -v 檢視是否安裝成功 修改maven配置檔案 apac
一篇文章搞定2017最新標題優化方法
很多人都說小2哥你為什麼一直都在寫直通車的文章?為什麼不寫寫自然搜尋方面的內容?你不知道我們新手更需要的就是這些免費流量的內容嗎? 我從13年開始寫文章,13年和14年我是寫自然搜尋寫的最多的,但是從15年開始的時候,我基本上寫的文章都是圍繞直通車。 其實這也是和我的
資料庫的原理,一篇文章搞定(一)
https://blog.csdn.net/zhangcanyan/article/details/51439012 一提到關係型資料庫,我禁不住想:有些東西被忽視了。關係型資料庫無處不在,而且種類繁多,從小巧實用的 SQLite 到強大的 Teradata 。但很少有文章講解資料庫是如何工作的。你可以自己
一篇文章搞定矩陣相關概念及意義--通俗解釋彙總
一篇文章理解矩陣在講什麼。 最近在學習矩陣相關知識,但是其抽象的解釋讓人摸不著頭腦,通過瀏覽一些部落格的內容和自己的理解,本文通過通俗的語言將矩陣的內涵做了總結。其中除了書本和個人觀點,部分引用部落格:。本文主要幫助大家理解矩陣,但不一定都是正確的,但願能起
資料庫的原理,一篇文章搞定(三)
合併聯接 合併聯接是唯一產生排序的聯接演算法。 注:這個簡化的合併聯接不區分內表或外表;兩個表扮演同樣的角色。但是真實的實現方式是不同的,比如當處理重複值時。 1.(可選)排序聯接運算:兩個輸入源都按照聯接關鍵字排序。 2.合併聯接運算:排序後的輸入源合併到一起。
Git | 一篇文章搞定Git、GitHub的理解和使用(學習筆記)
Git learning note 本筆記整理自廖雪峰老師的Git教程,加上了自己的實踐結果和一些理解,旨在使科研工作者(基本上是獨立開發的那種)看完就能理解和使用Git。廖老師的教程生動活潑,條理清晰,推薦閱讀。還可以贊助哦。 目錄 Git 簡
Python正則表達式很難?一篇文章搞定他,不是我吹!
編譯 返回 特殊字符 但是 參數 查找字符串 cas 行處理 產生 1. 正則表達式語法 1.1 字符與字符類 1 特殊字符:.^$?+*{}| 以上特殊字符要想使用字面值,必須使用進行轉義 2 字符類 1. 包含在[]中的一個或者多個字符被稱為字符類,字符類在匹
一篇文章搞定Python多程序(全)
1.Python多程序模組 Python中的多程序是通過multiprocessing包來實現的,和多執行緒的threading.Thread差不多,它可以利用multiprocessing.Process物件來建立一個程序物件。這個程序物件的方法和執行緒物件的方法差不多也有start(), run(), j
一篇文章搞定 Nginx 反向代理與負載均衡
## 代理 要想弄明白反向代理,首先要知道啥是正向代理,要搞懂正向代理只需要知道啥是代理即可。代理其實就是一箇中介,在不同事物或同一事物內部起到居間聯絡作用的環節。比如買票黃牛,房屋中介等等。 在網際網路中代理更多指的是代理伺服器,代理伺服器位於客戶端和伺服器之間,它充當兩者之間的中介。這
一篇文章搞懂DataSet、DataFrame、RDD-《每日五分鐘搞定大數據》
implicit 操作數 frame 大數據 函數 for 臨時 變量 ade 1. 三者共性: 1、RDD、DataFrame、Dataset全都是spark平臺下的分布式彈性數據集,為處理超大型數據提供便利 2、三者都有惰性機制,執行trainform操作時不會立即執