@RequestParam和@RequestBody的区别 (结合 Get/Post )
一、get方法
請求:例如http://127.0.01:1025/download?url=https://www.baidu.com&token=opera-dev
- 獲取請求參數:
二、post方法
請求: 如:
- 獲取請求參數:
三、Get與Post區別
Get和Post都是Http協議的組件,所以底層都是使用tcp鏈接。Get的請求方式是將http的header和data一并發往服務端,也就是一條tcp數據包發送,這就會有兩個問題:數據量有限,依賴于Tcp負載能力,所以攜帶的數據量很大的情況下,容易造成重發。有的攜帶的數據只能接受轉化成ASCII字符。但是Post不一樣,post使用兩步走,先發送http的header,然后再傳輸data。數據類型也不受限制。而且數據隱秘性比較好。
四、Get方式參數獲取
get請求方式參數是拼接在url后,所以限制了可以發送的長度。Get不支持使用http Body獲取參數,他只支持params,也就是URL拼接參數。如:
http://127.0.01:1025/download?url=https://www.baidu.com&token=opera-dev默認情況下會從Param(就是URL后面的拼接參數)獲取名字是id的項,自動轉化成Integer類型,其他的類型也是類似。
這個方法是獲取整個URL的信息,然后手動獲取和分離參數,和類型轉化。這個里面帶的內容很多,不僅Param還有Header,Cookies等。
五、Post方式參數獲取
post可以傳遞參數可以大致分成兩種:
- 一種是表單:在sevlet實現中mutipart/form-data和application/x-www-form-urlencoded會被特殊處理,請求參數將被放置于request.paramter,解析成map。
- 第二種,已application/json,參數是存放在json中的,參數必須要用@RequestBody才能解析出來。
- application/json和application/x-www-form-urlencoded區別
@RequestBody是將post請求中內容轉為一個整體對象。
- @RequestBody的解析有兩個條件:
- POST請求中content的值必須為json格式(存儲形式可以是字符串,也可以是byte數組)
- @RequestBody注解的參數類型必須是完全可以接收參數值的類型,比如:Map,JSONObject,或者對應的JavaBean;所以Integer類型不能作為@RequestBody注解的參數類型,將上述代碼修改如下(前端改成get請求)即可
1、使用@RequestBody 接收json字符串, Map,JSONObject,或者對應的JavaBean
@RequestMapping(value = "/download")public String getHtml(@RequestBody String json) {JSONObject jsonObject=JSON.parseObject(json);String url=jsonObject.getString("url");String token=jsonObject.getString("token");return " "; }@RequestMapping(value = "/download")public String getHtml(@RequestBody User user) {return user.getName(); }//Integer類型不能作為@RequestBody注解的參數類型 @RequestMapping(value = "/getUserInfo") public User getUserInfo(@RequestBody Integer id){ }2、使用@RequestParam
@RequestMapping(value = "/getUserInfo") public User getUserInfo(@RequestParam(value = "id",required = false) Integer id){ }這種方式只用在Content-Type=application/x-www-form-urlencoded這種情況下才能使用,sevlet將Body中的key-value轉成Param。
有一個有趣的現象:
- 如果Content-Type=mutipart/form-data,Body中加入參數和URL后面拼接參數一起做Post請求,都可以被加載到Param中,如果是同名的,只取用form-data中的。
- 如果Content-Type=application/x-www-form-urlencoded和URL拼接的一起,如果是String類型,則兩個值會被拼接,其他類型取的是URL拼接的參數。
??
和Get方式一樣,這是個通用的方式。這個也可以和URL拼接的一起搭,但是沒有RequestParam的String類型值被拼接問題,優先級 form-data高于URL拼接高于x-www-form-urlencoded。
六、@RequestParam注解
@Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface RequestParam {/*** 參數名稱(和value同等意思)*/@AliasFor("name")String value() default "";/*** 參數名稱 (和name同等意思)*/@AliasFor("value")String name() default "";/*** 是否必選(默認必選)*/boolean required() default true;/*** 參數默認值*/String defaultValue() default ValueConstants.DEFAULT_NONE;}- @RequestParam總體上來說,該注解類擁有三個參數:
- @RequestParam注解獲取的參數放在請求哪?
- 如何使用:
執行代碼:
結果:
id = 1, name = yc, age = 23代碼執行:
@Data @AllArgsConstructor @NoArgsConstructor public class User {private Integer id;private String name;private Integer age; }@RequestMapping(value = "/test", method = RequestMethod.GET)public void test(User user) {log.info("id = {}, name = {}, age = {}", user.getId(), user.getName(), user.getAge());}結果:
id = 1, name = yc, age = 23- 使用場景:
七、@RequestBody注解
@Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface RequestBody {/*** 默認參數必傳*/boolean required() default true;}required 默認為 true,即對象中的屬性必須有一個要傳,否則會拋出異常:
org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing- post請求的requestHeaders請求頭中有content-type字段,一般用來處理:applicatin/json格式的參數;
- Spring中的@RequestBody注解是用來接收請求體中的參數數據,即requestBody請求體中,故不受參數數據長度的限制;
使用Postman工具發送json格式的數據:
執行代碼:
@Data @AllArgsConstructor @NoArgsConstructor public class User {private Integer id;private String name;private Integer age;}@RequestMapping(value = "/test", method = RequestMethod.POST)public void test(@RequestBody User user) {log.info("id = {}, name = {}, age = {}", user.getId(), user.getName(), user.getAge());}結果:
id = 1, name = yc, age = 23請求的結果有持續性作用,例如:對數據庫添加、更新、刪除操作;
若使用Get請求,表單參數過長;
要傳送的數據不是采用7位的ASCII編碼;
- 測試三:使用Post請求,@RequestParam也可以接收參數;
注意:也可以使用這種方式用,發送Post請求,參數拼接到url之后,這是因為協議之間沒有做嚴格的區分,但這種方式不建議使用,這種方式就使用Get方式即可。例如:localhost:8888/optimus-prime/project/test?id=1&name=yc&age=23 使用瀏覽器請求數據,這種方式Get請求,但后端使用Post方式接收,訪問不成功!
執行代碼:
@PostMapping(value = "/test") public void test(@RequestParam("id") Integer id,@RequestParam("name") String name,@RequestParam("age") Integer age) {log.info("id = {}, name = {}, age = {}", id, name, age); }結果:
id = 1, name = yc, age = 12八、總結
對數據庫而言: get 請求不修改數據庫,只是查詢。Post是增加記錄,put是更新,Delete數據庫刪除;
Put,Post,Delete 方式的請求參數會直接放在requestBody里;
處理 request uri 部分的注解,路徑參數變量:@PathVariable;
處理request header部分的注解:@RequestHeader, @CookieValue,@RequestParam;
處理request body部分的注解:@RequestParam, @RequestBody;
綜上所述:@RequestParam注解既可以接收Get方式的請求頭中的參數,也可以接收Post方式的請求體中的參數;
application/x-www-form-urlencoded 這種就是一般的文本表單用 post 傳地數據,只要將得到的data 用 @RequestParam 或request.getParamter() 獲取即可;
multipart/form-data ,用于文件上傳,此時 form 的 enctype 屬性必須指定為 multipart/form-data;
application/json,將數據以json對象的格式傳遞;
text/xml;
put 和 delete 請求的headers 是有 content-type 這個字段的,只不過這兩個方法類型目前不常用;
參考文章
參考文章
總結
以上是生活随笔為你收集整理的@RequestParam和@RequestBody的区别 (结合 Get/Post )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 不玩虚的!深入B端SaaS产品设计核心理
- 下一篇: 2021年美食类短视频及直播营销趋势洞察