寫在前面
🛫更多知識總結見SpringBoot 2專欄
🚕本篇知識點總結自尚硅谷雷神的視頻
🚒博主對于該知識尚在學習階段
🚄如果發現存在問題請毫不吝嗇的指出
🚀🚀扎哇太棗糕的博客首頁🚀🚀
文章目錄
- 1 請求映射
- 1.1 Rest風格
- 1.2 表單提交Rest的原理
- 1.3請求映射的原理
- 2 請求處理常用注解
- 2.1 @RequestParam
- 2.2 @PathVariable
- 2.3 @RequestHeader
- 2.4 @RequestBody
- 2.5 @RequestAttribute
- 2.5 @RequestAttribute
- 3 方法參數小技巧
- 3.1 復雜參數屬性值
- 3.2 自定義參數實現數據綁定
1 請求映射
??在SpringBoot中使用@XxxMapping注解完成前端請求與后端方法的一個映射。以前的時候,通常使用url映射命名的方式完成增刪改查的操作,比如:/getUser 查找用戶/deleteUser 刪除用戶 /editUser更改用戶 /saveUser 添加用戶。但是,后來出現了Rest風格的請求方式一直沿用至今。
1.1 Rest風格
??Rest風格就是使用HTTP請求方式動詞來表示對資源的增刪改查等操作,比如:GET查找用戶DELETE刪除用戶PUT更改用戶 POST添加用戶。具體使用如下:
??但是前端form表單的method只有POST、GET兩種方法,如何使用PUT、DELETE兩種方法呢?這就使用到了HiddenHttpMethodFilter,在源碼的WebMvcAutoConfiguration自動配置類中使用OrderedHiddenHttpMethodFilter方法(方法源碼在下面),其中返回它同名類對象,該類向上兩層的父類HiddenHttpMethodFilter中定義了如何使用PUT、DELETE兩種方法(源碼見下面圖片)
@Bean
@ConditionalOnMissingBean({HiddenHttpMethodFilter.class})
// 這里的隱藏方法過濾器默認是不開啟的,通過下面的prefix和name即可在配置文件將其配置為true
@ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter",name = {"enabled"}
)
public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {return new OrderedHiddenHttpMethodFilter();
}
??了解源碼的規范之后,讓我們試著進行編碼,總結上述文字得知:若想使用Rest風格的請求,需要進行兩步操作①配置文件中開啟隱藏方法過濾器(據說高版本的SpringBoot源碼中默認是開啟的)②form表單的method為POST并加入_method的值為相應的PUT、DELETE
1.2 表單提交Rest的原理
??表單在使用Rest風格的請求方式提交的時候,會帶上input標簽里_method的對應值PUT、DELETE,當請求發送過來的時候將會被HiddenHttpMethodFilter所攔截進行判斷(form表單的method是否為POST且無報錯),判斷通過之后獲取_method對應的值。原生request(post)的包裝模式xxxWrapper重寫了getMethod方法,返回的是_method傳入的值。后面的controller方法中url映射的method的值就是經過方法重寫之后獲得的傳入值。
?? 像form表單的method只有POST、GET兩個值的情況需要將配置文件中的隱藏方法過濾器開啟,別的如PostMan直接發送Put、delete等方式請求就無需使用HiddenHttpMethodFilter
? ?根據四種配置演變出的四個新注解? ?自定義_method名稱的方法:自定義一個webConfig類類中來創建一個HiddenHttpMethodFilter方法,調用它的setMethodFilter方法即可實現定制
1.3請求映射的原理
??SpringBoot和SpringMVC一樣,前端發送的所有請求都一定會到DispatcherServlet中,而DispatcherServlet本身就是一個servlet繼承自HttpServlet。一個servlet必定會重寫doGet和doPost方法,于是通過對源碼進行分析發現在HttpServlet的子類FrameworkServlet(它同時也是DispatcherServlet的父類)中重寫了doGet和doPost方法,并且重寫之后的doXxx方法都是調用了本類的processRequest方法,這個方法的底層又調用了本類的doService抽象方法,抽象方法沒有方法體,繼承該類的子類必須重寫該方法,于是乎在它的子類中找到了重寫之后的doService方法,這個方法中除了前面一大堆的初始化之外調用本類的doDispatch方法(這個才是最重要的一個方法)
??從上文的析得知,SpringMVC的功能都要從DispatcherServlet類的doDispatch方法中分析得出,此方法使用getHandler(processedRequest)有參構造器里的對獲取到的所有請求使用for循環逐個匹配下面的handlerMappings,而前兩個都是在WebMvcAutoConfiguration自動配置類中配置過的。
? ?拓展知識:如果一些特殊場景需要對不同的請求映射不同的代碼包,比如普通用戶和VIP用戶的功能肯定是不一樣的,所以在此時我們就可以借助給容器中注冊自定義HandlerMapping的方式來完成。
2 請求處理常用注解
??以下的注解都可以通過鍵名獲取單個鍵的值,也可以使用map集合(kv都是必須String)獲取所有的參數
2.1 @RequestParam
??@RequestParam注解用來獲取請求參數的值
2.2 @PathVariable
??在Restful請求風格中,通常使用路徑的方式進行參數的傳遞,@PathVariable注解就是用來獲取url路徑中參數的值
2.3 @RequestHeader
??@RequestHeader注解用來獲取請求頭的值
2.4 @RequestBody
??@RequestBody注解用來獲取請求體的值
2.5 @RequestAttribute
??@RequestAttribute用來獲取request域的值,兩種獲取方式:①直接@RequestAttribute注解 ②HttpServletRequest對象的getAttribute方法。這個注解無法使用map獲取所有的值
2.5 @RequestAttribute
??使用session.set(k, v)設置的屬性值存儲在session中,而每個用戶都有其唯一對應的jsessionid保存在cookie中,每次發送請求cookie都會攜帶這個jsessionid,服務器通過jsessionid解析出session對象之后再調用get(k)方法獲取對應的屬性值。
??但是現在有這么一個情況,在頁面開發的時候禁用了cookie(相當于session也失效了),這個時候怎么獲取屬性值?通過url重寫使用矩陣變量的方式進行傳遞。使用該方法需要有以下兩步:
第一步: SpringBoot默認禁用矩陣變量,可通過自定義配置類向容器注冊WebMvcConfigurer組件替代默認的組件來開啟矩陣變量
第二步: 分單矩陣和多矩陣兩種用法
3 方法參數小技巧
3.1 復雜參數屬性值
??方法中有時會傳入一些復雜的參數,比如Map、Model、request、response等,其中前三種參數的設置的屬性值數據都會存放在request請求域中。接下來使用代碼證實一下這個說法:
3.2 自定義參數實現數據綁定
??頁面提交的請求數據(GET、POST)都可以和自定義對象參數的屬性(也就是POJO類的參數)進行綁定