一次与玄学的战争(革命已成功)
相信各位读者中一定有遇到过玄学的,玄学是什么?别问我。
今晚在制作图片上传功能的时候,就遇到了一个让我百思不得其解的玄学。
在文件上传中有这么一句代码 request.getPart("sessionID");
,这是用来验证用户身份的,又因为是文件上传,使用的请求格式是 multi-part,所以只能用 getPart()
来获取参数。在官方文档中提到了可能抛出的异常,其中一个是
IllegalStateException – if the request body is larger than maxRequestSize, or any Part in the request is larger than maxFileSize
而在 getPart()
所在 try
的 catch
中,IllegalStateException
是不被要求捕获的,所以一旦上传文件大小超出了设置的极限,tomcat 就会进入 500 界面。而我想在 IllegalStateException
发生的时候将其捕获,好了,这下玄学出现了,如果我捕获了这个异常,则在浏览器上会发现产生了 net::ERR_CONNECTION_RESET
。WTF!
目前我还在摸索,不知道该怎么解决。如果有哪位大神知道解决方案,那麻烦请戳下面的 QQ 联系我。
好了,我已经知道怎么解决这个玄学了。
测试所在的环境
- Chrome 56.0.2924.67 Beta
- Kubuntu 15.10
- Tomcat
78
万分无奈的我选择了使用 WireShark 进行 TCP 层面上的审查,结果我发现了如下的情况
- 我没有捕获
IllegalStateException
- 此时浏览器会向服务器传送大量的数据
- 服务器在接收数据超出了设定的范围后抛出
500
错误 - 浏览器继续传输大量数据直至结束
- 服务器发送
RST
包 - Chrome Dev Tools 显示状态为
500
- 我捕获了
IllegalStateException
并且输出了回应- 浏览器向服务器发送大量的数据
- 浏览器在接收数据超出了设定的范围后抛出
IllegalStateException
并被捕获,向浏览器做出回应 - 浏览器继续传输大量数据直至结束
- 服务器发送
RST
包 - Chrome Dev Tools 显示状态为
net::ERR_CONNECTION_RESET
然后我思考了两个情况的异同
- 两种情况在服务器都会向浏览器发送 HTTP 回应
- 两种情况服务器都会发送
RST
包 - 浏览器在接收到
500
状态时显示出了服务器的回应
所以我猜测是不是当状态码是 200
且在数据传送完成后服务器发送了 RST
包时,Chrome 会认为这一次数据传输是失败的。所以我尝试在对 IllegalStateException
的异常处理中将状态码设置为了 400 Bad Request
,重启服务器测试,成功!
好吧,我不知到给怎么评价这一个玄学,只能说 WireShark 是解决网络错误的利器。
现在我可以上传图片了!