You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用MultipartFormEntity发送File与byte[]的差异及问题排查

问题原因分析

当你使用addBinaryBody("content", fileBytes)创建multipart实体时,Apache HttpClient默认会将字节数组当作文本类型字段处理,自动对原始字节进行Base64编码后发送。这就导致服务器端@RequestParam("content") byte[]接收到的是Base64编码后的字节数组,而非原始文件字节——Base64编码会让数据体积增加约33%(298254 * 1.33 ≈ 347739),正好和你看到的结果匹配。

而使用addBinaryBody("content", file)时,HttpClient会自动识别这是文件类型,以原始二进制流的形式发送,不会进行编码,因此服务器端的MultipartFile能正确解析出原始字节数。

你尝试添加ContentType.BINARY_FILE和filename.bin参数后,HttpClient会将该字段当作文件部件发送,这时候服务器的MultipartFile接口能正确处理(因为它专门适配multipart文件部件),但@RequestParam("content") byte[]仍然无法正确获取原始字节的原因是:Spring对于@RequestParam接收multipart请求中二进制部件的逻辑,不会自动提取原始二进制内容,而是仍按文本字段的解析逻辑处理。

解决方案

方案1:让HttpClient发送未编码的原始字节数组

在调用addBinaryBody时,显式指定ContentType.APPLICATION_OCTET_STREAM,强制HttpClient将字节数组作为二进制字段发送,避免Base64编码:

var fileBytes = Files.readAllBytes(Path.of(path));
HttpEntity multipartByteArr = MultipartEntityBuilder.create()
        .addBinaryBody("content", fileBytes, ContentType.APPLICATION_OCTET_STREAM, null)
        .build();

这样服务器端的byteArr接口就能接收到和原始文件一致的字节数。

方案2:调整服务器端接口适配multipart请求

如果不需要单独的byteArr接口,直接复用multipart接口即可,在方法内部将MultipartFile转为字节数组:

@PostMapping("multipart")
public void multipart(@RequestParam("content") MultipartFile file) throws IOException {
    byte[] fileBytes = file.getBytes();
    System.out.println(fileBytes.length);
}

或者将byteArr接口改为使用@RequestPart接收:

@PostMapping("byteArr")
public void byteArr(@RequestPart("content") byte[] fileBytes) {
    System.out.println(fileBytes.length);
}

内容的提问来源于stack exchange,提问作者diogoaos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 10:52:41