@RequestParam,@RequestBody,@ResponseBody,@PathVariable註解的一點小總結
一、前提知識:
-
-
發送GET請求是沒有請求體的,參數會直接拼接保留到url後一併發送;
-
而POST請求是帶有請求體的,帶着請求體一併發送,每次請求請求體只會有一個;
二、註解介紹
@RequestParam註解:將返回到後端的請求參數綁定到控制器方法參數,該註解有兩個需要了解的屬性
-
一個是required屬性,默認是true
當該屬性為true的時候,且指定了value屬性時,如果前台頁面的key跟接收的value不同是是會報400錯誤的;
而當該屬性為false的是會,即使key不存在,也不會報400的錯;
⚠️但是當後面的參數的基本數據類型的時候,是會報500錯誤的,因為當找不到值的時候,會默認返回一個null,基本數據類型接收到null,直接就會報錯,解決方法就是使用對應的引用類型去接收,即使時null也不會報錯
-
另一個是defaultValue屬性,默認值是16個Unicode字符
使用了該屬性之後,且指定了value屬性,但是前端頁面並沒有給對應的key時,就會默認採用這個自動值,底層會幫我們自動轉換成參數類型
⚠️ 綁定的方法參數是附加到url後的[key-value]格式的值,進而衍生出也可以是數組、對象或者集合,接下來會進行演示
@RequestBody跟@ResponseBody:這兩個註解的作用其實是一樣的,處理的都是json字符串,只不過前一個註解是從前往後傳,第二個註解是從後往前傳,接下來也會樣式這兩個註解的使用方式
⚠️ 所以講到這裡其實應該明白,@RequestBody註解在一個方法中只會出現一次,而@RequestParam則可以出現多個,這是因為@RequestBody接收的是整個請求體的json格式化字符串,而@RequestParam接收的是附加到url後面的[key-value]形式值,會存在多個這樣的值,所以自然也可以使用多個@RequestParam註解來接收,如果是較少的參數那還好,如果太多的參數,一個一個獲取就太麻煩了,而且寫出來的代碼也不夠優雅整潔。
@PathVariable的作用其實就是接收url後面傳過來的變量,這個註解使用起來很簡單
三、註解的簡單演示
是基於springboot環境,使用postman來測試
一、@RequestParam註解
-
簡單使用,接收url後面的 key-value值
//測試的接口 : localhost:8080/testRequestParam/one?name=Amg&age=22 @RestController @RequestMapping("/testRequestParam") public class TestRequestParamAnno { @GetMapping("/one") public Result one(@RequestParam(value = "name") String name, @RequestParam(value = "age") int age){ System.out.println(name + " / " + age); return ResultGenerator.getSuccessful(name + " / " + age); } } //output ResultGenerator返回的是一個對象,通過@ResponseBody轉換成json字符串格式 { "code": 200, "msg": "Amg / 22" }
2.測試添加required屬性跟defaultValue屬性
//測試的接口: localhost:8080/testRequestParam/two?name=Amg&= @GetMapping("/two") public Result two(@RequestParam(value = "name") String name, @RequestParam(value = "age") int age) { System.out.println(name + " / " + age); return ResultGenerator.getSuccessful(name + " / " + age); } //output 這是由於返回的url中沒有 age 這個key,所以報400錯誤,這是很常見的一種錯誤 { "timestamp": "2020-09-26T07:22:51.449+00:00", "status": 400, "error": "Bad Request", "trace": "org.springframework.web.bind.MissingServletRequestParameterException: Required int parameter 'age' is not present "message": "Required int parameter 'age' is not present", "path": "/testRequestParam/two" } //此時可以通過給默認值來解決 @GetMapping("/two") public Result two(@RequestParam(value = "name") String name, @RequestParam(value = "age" ,defaultValue = "1") int age) { System.out.println(name + " / " + age); return ResultGenerator.getSuccessful(name + " / " + age); } //output { "code": 200, "msg": "Amg / 1" }
3.如果url後有多個key值,那麼如此一個一個的接收就會顯得很麻煩,而且方法參數也會很膨脹,一點都不優雅,其實我們還可以這樣操作
//這種寫法就會使得方法參數很膨脹(不建議使用),其實我們只需要改造一下 public Result three(@RequestParam(value = "name") String name, @RequestParam(value = "age") int age, @RequestParam(value = "gender") String gender, @RequestParam(value = "lover") String lover, @RequestParam(value = "weight") double weight ){ } //用一個Map來接收所有的key,value值 @GetMapping("three") public Result three(@RequestParam Map<String,Object> map){ StringBuilder sb = new StringBuilder(); map.forEach((key,value) -> { sb.append(key + " / " + value + "; "); }); return ResultGenerator.getSuccessful(sb.toString()); } //output { "code": 200, "msg": "name / Amg; age / 22; gender / 男; lover / guess; weight / guess; " }
二、@Requestbody和@ResponseBody
//首先構造一個對象,使用lombok插件給getter/setter和tostring方法 @Data @ToString public class User { private String name; private Integer age; private String gender; }
1.接收前台返回來的json字符串,並且封裝到User對象裏面
(題外話:前台頁面可以使用JSON.stringify函數把元素打成json串,指定內容格式為json,發送ajax請求到後台)
@GetMapping("/one") @ResponseBody public Result one(@RequestBody User user){ return ResultGenerator.getSuccessful(user.toString()); } //預估會接收一個json串,然後又傳回去(別糾結,只是做演示,正常會有邏輯操作)
發生了405錯誤,這是因為我們在錯誤的地方使用了POST請求,後台接收用了Get請求,沒有對上,這也是非常常見的錯誤,修改方法也很簡單 把後台的Get請求修改成Post請求(一般使用這種) 前台發送Get請求 //修改過後 //output { "code": 200, "msg": "User(name=Amg, age=22, gender=男, motto=該吃吃,該喝喝,遇事別往心裏擱)", "data": null }
至於@ResponseBody註解的演示,可是一直有在用,返回去的格式就是json格式串
三、@PathVariable
剛剛說了,該註解是接收url後面的變量的,使用起來也很方便,看一個小例子
//測試的接口:localhost:8080/testPathVariable/one/3024166 @GetMapping("/one/{id}") public Result one(@PathVariable("id") String id){ return ResultGenerator.getSuccessful("接收回來的路徑是:" + id); } //output { "code": 200, "msg": "接收回來的路徑是:3024166", "data": null }
以上註解都是日常工作中會用到的,今天抽了點時間做個小總結… 是時候打遊戲去了(遊戲不香嘛!!)
最後,感謝你的觀看,如果覺得有收穫的話,請幫忙點個贊
(關注公眾號:碼農Amg ,一位剛畢業的搬磚工,會不定期的分享工作中遇到的坑和學習小總結,時常還會分享沙雕日常,歡迎胖友們一起溝通交流)
一起努力學習,天天向上(emmm我們下期見吧,休息一下吧)