AJAX传输BLOB至Java服务器转字节数组时程序挂起求助
问题:AJAX上传BLOB图片到Java服务器时,IOUtils.toByteArray挂起无法继续
我最近在做一个功能,通过AJAX把BLOB图片发给Java服务器,想转成byte数组保存。现在已经拿到了BufferedInputStream,但调用IOUtils.toByteArray(bis)的时候程序直接挂住了,完全没法继续。下面是我的代码,有没有大佬能帮忙看看问题出在哪?
客户端AJAX代码:
$.ajax({ type: "POST", url: "/com/uploadImage/", data: blobImage, cache: false, contentType: false, processData: false, success: function (data) { console.log(data); } });
Java服务器代码:
public void handleRequest() { try { BufferedInputStream bis = new BufferedInputStream(this.getSocket().getInputStream()); // 就是这一行导致程序挂起 byte[] bytes = IOUtils.toByteArray(bis); FileUtils.writeByteArrayToFile(new File("image.png"), bytes); } catch (Exception e) { e.printStackTrace(); } }
可能的原因和解决方案:
1. 直接读取Socket InputStream不符合HTTP协议规范
你现在的Java代码是直接操作Socket的输入流,但AJAX发的是HTTP POST请求,HTTP请求是有完整结构的:请求头 + 请求体。IOUtils.toByteArray(bis)会一直尝试读取流直到它结束,但TCP Socket连接在HTTP请求完成后默认是保持长连接的(除非请求头里指定Connection: close),所以输入流不会主动终止,程序就会一直挂着等后续数据。
解决方案:
- 优先改用Servlet、Spring MVC这类Web框架来接收请求。这些框架会自动解析HTTP协议,帮你处理请求头和请求体的分离,你只需要通过
request.getInputStream()读取请求体的内容即可,框架会负责流的正确关闭和请求结束的判断。 - 如果非要自己用Socket处理HTTP请求,必须先解析HTTP请求头,获取
Content-Length字段的值,然后只读取对应长度的字节数,而不是读取整个流到结束。示例代码如下:
// 先解析HTTP头部,拿到Content-Length(这里需要自己实现头部解析逻辑) int contentLength = ...; byte[] bytes = new byte[contentLength]; bis.read(bytes); // 然后再保存文件 FileUtils.writeByteArrayToFile(new File("image.png"), bytes);
2. 客户端AJAX的请求格式潜在小问题
虽然你设置了contentType: false和processData: false,直接传Blob时浏览器会自动生成Content-Type为application/octet-stream,这个一般不会导致挂起,但可以在浏览器开发者工具里检查请求头部是否包含正确的Content-Length,确保服务器能拿到准确的请求体长度。
内容的提问来源于stack exchange,提问作者DM5963
相关产品推荐
相关产品推荐

