目錄
1. @RequestParam(value = "listId") Integer id:Required Integer parameter 'listId' is not present
2. 將@RequestParam修改爲@RequestBody:JSON parse error
POST請求接口,前端參數調用爲post調用,即封裝body調用(如下),出現異常。
{
"listId": 123
}
1. @RequestParam(value = "listId") Integer id:Required Integer parameter 'listId' is not present
org.springframework.web.bind.MissingServletRequestParameterException: Required Integer parameter 'listId' is not present
@RequestMapping(value = "/updateXXX", method = RequestMethod.POST)
public JsonResult<Boolean> updateXXX(@RequestParam(value = "listId") Integer id) {}
接口請求url如下:
request url: http://XXX/updateXXX?listId=1
1.1 原因
GET把參數包含在URL中,POST通過request body傳遞參數。
@RequestParam接收的參數是來自requestHeader中,即請求頭。@RequestBody接收的參數是來自requestBody中,即請求體。
因使用@RequestParam,所以接口請求url如上,但POST請求,所以會去request body裏尋找參數值,所以會找不到參數。
2. 將@RequestParam修改爲@RequestBody:JSON parse error
org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of `java.lang.Integer` out of START_OBJECT token
@RequestMapping(value = "/updateXXX", method = RequestMethod.POST)
public JsonResult<Boolean> updateXXX(@RequestBody Integer listId) {}
2.1 原因
@RequestBody是將post請求中content值轉爲一個整體對象。@RequestBody的解析有兩個條件:
1. POST請求中content的值必須爲json格式(存儲形式可以是字符串,也可以是byte數組);所以會出現JSON parse error
2. @RequestBody註解的參數類型必須是完全可以接收參數值的類型,比如:Map,JSONObject,或者對應的JavaBean。
所以Integer類型不能作爲@RequestBody註解的參數類型
3. 將Integer修改爲String
@RequestMapping(value = "/updateXXX", method = RequestMethod.POST)
public JsonResult<Boolean> updateXXX(@RequestBody String listId) {}
接口請求url如下:
request url: http://XXX/updateXXX
swagger接口如下:
當前POST請求中content的值存儲形式就是字符串,這樣使用postman發起請求或者前端請求時,請求body就必須下方格式,不太直觀,也不規範,所以不建議使用
{
123
}
4. 將參數修改爲一個實體類封裝listId
最終使用當前方式
5. 建議
一般情況下,get請求參數使用@RequestParam;post請求使用@RequestBody
6. GET和POST區別
-
GET在瀏覽器回退/刷新是無害的;而POST數據會被重新提交。
-
GET產生的URL地址收藏爲書籤;而POST不可以。
-
GET請求會被瀏覽器主動cache;而POST不會,除非手動設置。
-
GET請求只能進行url編碼(application/x-www-form-urlencoded);而POST支持多種編碼方式。
-
GET請求參數會被完整保留在瀏覽器歷史記錄裏;而POST中的參數不會被保留。
-
當發送數據時,GET 方法向 URL 添加數據,URL 的長度是受限制的(URL 的最大長度是 2048 個字符);而POST無限制。
-
對參數的數據類型,GET只接受ASCII字符;而POST沒有限制。
-
GET安全性較差,因爲所發送的數據是URL的一部分,參數直接暴露在URL上,所以不能用來傳遞敏感信息;而POST安全性較好,因爲參數不會被保存在瀏覽器歷史或web服務器日誌中。
-
GET參數通過URL傳遞所有人可見;而POST放在Request body中。
看到了有趣的說法:
GET和POST是什麼?HTTP協議中的兩種發送請求的方法。HTTP是什麼?HTTP是基於TCP/IP的關於數據如何在萬維網中如何通信的協議。HTTP的底層是TCP/IP。所以GET和POST的底層也是TCP/IP,也就是說,GET/POST都是TCP鏈接。GET和POST能做的事情是一樣一樣的。你要給GET加上request body,給POST帶上url參數,技術上是完全行的通的。
所以說:GET和POST本質上就是TCP鏈接,並無差別。但是由於HTTP的規定和瀏覽器/服務器的限制,導致他們在應用過程中體現出一些不同。
GET和POST還有一個重大區別,簡單的說:GET產生一個TCP數據包;POST產生兩個TCP數據包。
對於GET方式的請求,瀏覽器會把http header和data一併發送出去,服務器響應200(返回數據);
而對於POST,瀏覽器先發送header,告訴服務端等一下會有數據過來,服務端響應100 continue,告訴瀏覽器我已經準備接收數據,瀏覽器再post發送一個data給服務端,服務器響應200 ok(返回數據)。
多發的那個expect 100 continue header報文,是由客戶端對http的post和get的請求策略決定的,目的是爲了避免浪費資源,如帶寬,數據傳輸消耗的時間等等。所以客戶端會在發送header的時候添加expect 100去探探路,如果失敗了就不用繼續發送data,從而減少了資源的浪費。所以是否在發送一個包取決了客戶端的實現策略,和get/post並沒什麼關係。有的客戶端比如fireFox就只發送一個包。