客戶端傳遞數據過大導致服務端拋異常

今天碰到一個服務端拋出的一個異常如下:

Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing

在客戶端看到的異常爲:

java.io.IOException: Server returned HTTP response code: 400 for URL: http://localhost:XXXXXX
	at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1894)
	at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)
	

這個異常出現在前面若干條數據都正常,到了大概第十條的時候出現這個問題,這個咋看是類似於服務端的某個緩存沾滿,導致服務端取客戶端接受的數據時候出現的異常;後來查看發現,是因爲後面傳過去的數據已經超出了限制,這就讓我去扒拉了一下,POST請求和GET請求傳遞的數據的最大值限制(一下部分引用其他博客);

雖然post請求對外是說打下無限制,但是一般傳遞的數據大小盡量保持在2M之內,因爲太大會拋上面這個異常,這個也和服務端的配置有關;因此在寫代碼之前也需要估計一下傳遞數據的大小;

兩種請求方式底層實現都是基於TCP/IP協議,所謂的請求長度限制是由瀏覽器和 web 服務器決定和設置的,各種瀏覽器和 web 服務器的設定

均不一樣,這依賴於各個瀏覽器廠家的規定或者可以根據 web 服務器的處理能力來設定。

關於GET以及POST的區別

  1. GET產生一個TCP數據包;POST產生兩個TCP數據包。對於GET方式的請求,瀏覽器會把http header和data一併發送出去,服務器響應200(返回數據);多數瀏覽器對於POST採用兩階段發送數據的,先發送請求頭,再發送請求體,即使參數再少再短,也會被分成兩個步驟來發送(相對於GET),也就是第一步發送header數據,第二步再發送body部分。HTTP是應用層的協議,而在傳輸層有些情況TCP會出現兩次連結的過程,HTTP協議本身不保存狀態信息,一次請求一次響應。對於TCP而言,通信次數越多反而靠性越低,能在一次連結中傳輸完需要的消息是最可靠的,儘量使用GET請求來減少網絡耗時。如果通信時間增加,這段時間客戶端與服務器端一直保持連接狀態,在服務器側負載可能會增加,可靠性會下降。
  2. GET請求能夠被cache,GET請求能夠被保存在瀏覽器的瀏覽歷史裏面(密碼等重要數據GET提交,別人查看歷史記錄,就可以直接看到這些私密數據)POST不進行緩存。
  3. GET參數是帶在URL後面,傳統IE中URL的最大可用長度爲2048字符,其他瀏覽器對URL長度限制實現上有所不同。POST請求無長度限制(目前理論上是這樣的)。
  4. GET提交的數據大小,不同瀏覽器的限制不同,一般在2k-8K之間,POST提交數據比較大,大小靠服務器的設定值限制,而且某些數據只能用 POST 方法「攜帶」,比如 file。
  5. 全部用POST不是十分合理,最好先把請求按功能和場景分下類,對數據請求頻繁,數據不敏感且數據量在普通瀏覽器最小限定的2k範圍內,這樣的情況使用GET。其他地方使用POST。
  6. GET 的本質是獲取,而 POST 的本質是傳遞。而且,GET 是「冪等」的,在這一點上,GET 被認爲是「安全的」。但實際上 server 端也可以用作資源更新,但是這種用法違反了約定,容易造成 CSRF(跨站請求僞造)。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章