今天碰到一个服务端抛出的一个异常如下:
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的区别
- GET产生一个TCP数据包;POST产生两个TCP数据包。对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);多数浏览器对于POST采用两阶段发送数据的,先发送请求头,再发送请求体,即使参数再少再短,也会被分成两个步骤来发送(相对于GET),也就是第一步发送header数据,第二步再发送body部分。HTTP是应用层的协议,而在传输层有些情况TCP会出现两次连结的过程,HTTP协议本身不保存状态信息,一次请求一次响应。对于TCP而言,通信次数越多反而靠性越低,能在一次连结中传输完需要的消息是最可靠的,尽量使用GET请求来减少网络耗时。如果通信时间增加,这段时间客户端与服务器端一直保持连接状态,在服务器侧负载可能会增加,可靠性会下降。
- GET请求能够被cache,GET请求能够被保存在浏览器的浏览历史里面(密码等重要数据GET提交,别人查看历史记录,就可以直接看到这些私密数据)POST不进行缓存。
- GET参数是带在URL后面,传统IE中URL的最大可用长度为2048字符,其他浏览器对URL长度限制实现上有所不同。POST请求无长度限制(目前理论上是这样的)。
- GET提交的数据大小,不同浏览器的限制不同,一般在2k-8K之间,POST提交数据比较大,大小靠服务器的设定值限制,而且某些数据只能用 POST 方法「携带」,比如 file。
- 全部用POST不是十分合理,最好先把请求按功能和场景分下类,对数据请求频繁,数据不敏感且数据量在普通浏览器最小限定的2k范围内,这样的情况使用GET。其他地方使用POST。
- GET 的本质是获取,而 POST 的本质是传递。而且,GET 是「幂等」的,在这一点上,GET 被认为是「安全的」。但实际上 server 端也可以用作资源更新,但是这种用法违反了约定,容易造成 CSRF(跨站请求伪造)。