Spring Boot中Multipart请求客户端调用失效问题求助
哥们,看你被这个问题卡了一周太闹心了!Postman正常但客户端调用请求到不了控制器,90%是客户端的Multipart请求格式不符合标准,Spring Boot的Multipart解析器对格式要求挺严格的,咱们一步步来修复:
1. 先改客户端最致命的错误:Content-Type设置错误
你客户端代码里写的是:
connection.setRequestProperty("Content-Type", "form-data; boundary=" + boundary);
这完全不对!标准的Multipart请求Content-Type必须是multipart/form-data,少了multipart/前缀会导致Spring Boot根本识别不出这是Multipart请求,直接就把请求拦截了,自然到不了控制器。
修改成:
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
2. 修正客户端的Multipart请求格式细节
Spring Boot对Multipart的字段格式要求很严谨,你需要调整几个点:
- 给文件字段加上
filename属性,很多解析器会因为缺少这个属性忽略文件参数 - 确保CRLF是标准的
\r\n,避免自定义常量出问题 - 调整流的flush和关闭顺序,防止数据截断
先定义标准的CRLF:
private static final String CRLF = "\r\n";
然后修改文件上传的代码块:
// Send file writer.append("--" + boundary).append(CRLF); // 这里必须加上filename字段,Spring解析更稳定 writer.append("Content-Disposition: multipart/form-data; name=\""+PESConstants.PARAM_PDF+"\"; filename=\"uploaded.pdf\"").append(CRLF); writer.append("Content-Type: application/pdf").append(CRLF); writer.append("Content-Transfer-Encoding: binary").append(CRLF); writer.append(CRLF).flush(); // 先刷出头部信息 output.write(pdfFile); output.flush(); output.close(); // 确保二进制文件的所有字节都发送出去 writer.append(CRLF).flush(); // End of multipart/form-data. writer.append("--" + boundary + "--").append(CRLF).flush(); writer.close();
3. 清理Spring Boot控制器的冗余代码
你控制器里写了boolean isMultipartContent = ServletFileUpload.isMultipartContent(request);,这完全没必要!Spring Boot已经帮你完成了Multipart请求的解析和封装,自己调用Servlet的判断方法反而会干扰Spring的处理逻辑,直接删掉这行。
另外,不要混用Spring MVC和Jersey的注解!你用的是@RestController(Spring MVC的注解),就老老实实使用@RequestParam接收MultipartFile,换成Jersey的@FormDataParam会导致Spring无法正确解析参数,出现InputStream为空的情况。
4. 可选:检查Spring Boot的Multipart配置
如果你的上传文件比较大,默认配置可能会拦截请求,在application.properties里添加以下配置:
spring.servlet.multipart.max-file-size=10MB spring.servlet.multipart.max-request-size=10MB
根据你的实际文件大小调整数值即可。
5. 调试技巧:抓包对比请求格式
用Charles或Wireshark抓一下客户端发送的请求,再对比Postman的请求格式,重点看:
- Content-Type是否正确
- Boundary分隔符是否和请求里的一致
- 每个参数的
Content-Disposition格式是否标准 - 二进制文件数据是否完整
按照上面的步骤改完,应该就能解决请求到不了控制器的问题了。
内容的提问来源于stack exchange,提问作者Bam

