客户端传递数据过大导致服务端抛异常

今天碰到一个服务端抛出的一个异常如下:

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(跨站请求伪造)。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Lua是一种轻量级的、高效的脚本语言,广泛应用于游戏开发、嵌入式系统、网络编程等领域。下面是使用Lua实现客户端实现二维码扫描传递给服务端的消息的代码: ```lua -- 导入必要的库 local json = require("json") local socket = require("socket") local http = require("socket.http") -- 创建socket连接 local client = socket.tcp() client:connect("127.0.0.1", 8000) -- 扫描二维码获取到的信息 local scan_result = "https://www.example.com" -- 构造消息体 local message = { type = "scan_result", data = { result = scan_result } } -- 将消息体编码为JSON格式 local json_message = json.encode(message) -- 发送消息 client:send(json_message .. "\n") -- 等待服务端响应 local response = client:receive() -- 解析服务端响应 local response_message = json.decode(response) -- 处理服务端响应 if response_message.type == "success" then print("消息发送成功!") else print("消息发送失败:" .. response_message.error) end -- 关闭socket连接 client:close() ``` 这段代码首先导入了必要的库,包括json用于编解码JSON格式的数据,socket用于创建TCP连接,http用于发送HTTP请求。然后创建了一个TCP连接并连接到指定的服务端。接下来,构造了一个包含扫描结果的消息体,并将其编码为JSON格式。然后发送消息体到服务端,并等待服务端响应。最后解析服务端响应并根据响应结果进行处理,最后关闭socket连接。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值