Required Integer parameter 'listId' is not present、JSON parse error

目錄

1. @RequestParam(value = "listId") Integer id:Required Integer parameter 'listId' is not present

1.1 原因

2. 將@RequestParam修改爲@RequestBody:JSON parse error

2.1 原因

3. 將Integer修改爲String

4. 將參數修改爲一個實體類封裝listId

5. 建議

6. GET和POST區別


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就只發送一個包。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章