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

Spring RestTemplate跨微服务传视频文件序列化异常修复

问题产生原因

报错的核心原因是App A转发文件时的参数传递逻辑错误:

  • 你直接将Spring MVC接收到的MultipartFile实例放入RestTemplate的请求体中,RestTemplate默认使用Jackson对请求内的Java对象做序列化处理
  • MultipartFile是Spring针对服务端接收上传文件封装的对象,内部持有FileInputStream、FileDescriptor这类和本地操作系统文件句柄绑定的资源属性,这类属性没有可供Jackson序列化的字段,也无法被序列化成网络传输的内容,最终触发序列化失败异常。
修复方案

不要直接传递MultipartFile对象,将文件内容转换为Spring支持的Multipart资源类型后再放入请求体,RestTemplate会自动按form-data的二进制流规则组装请求,不会触发Jackson对象序列化逻辑。

具体修改步骤

  1. 修改App A中AppBService的sendToB方法,将MultipartFile转换为ByteArrayResource传递,同时重写资源的getFilename方法保证下游服务能正常识别文件名,修改后代码如下:
import org.springframework.core.io.ByteArrayResource;
import java.io.IOException;

// 其余导入保持不变

@Service
public class AppBService {

    public String sendToB(MultipartFile file) throws ResponseStatusException, IOException {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
        
        // 核心替换:将MultipartFile转为可传输的字节数组资源
        ByteArrayResource fileResource = new ByteArrayResource(file.getBytes()) {
            @Override
            public String getFilename() {
                // 必须返回原始文件名,否则App B无法正常解析文件字段
                return file.getOriginalFilename();
            }
        };
        body.add("file", fileResource);
        
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
        String serverUrl = "http://127.0.0.1:8090/makeFrames";
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> response = restTemplate.exchange(
                serverUrl,
                HttpMethod.POST,
                requestEntity,
                String.class
        );
        if (response.getStatusCode() != HttpStatus.OK) {
            throw new ResponseStatusException(response.getStatusCode(), response.getBody());
        }
        return response.getBody();
    }
}
  1. (可选优化)如果传输的视频文件体积较大,为了避免全量读入字节数组占用过高内存,可以将MultipartFile转为临时文件后用FileSystemResource传递,示例代码片段:
// 大文件传输替换逻辑
File tempFile = File.createTempFile("upload-", file.getOriginalFilename());
file.transferTo(tempFile);
body.add("file", new FileSystemResource(tempFile));
// 请求完成后记得删除临时文件避免磁盘占用
tempFile.deleteOnExit();
  1. (额外问题修正)你当前AppAController的依赖注入写法存在语法错误,@Autowired标注在final字段上无法完成注入,建议改成构造器注入,或者移除字段的final修饰,该问题不影响本次序列化报错,但会导致应用启动失败。

修改完成后重启App A,再通过Postman发送请求即可正常完成文件转发,App B可以正常接收到视频文件并执行关键帧提取逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 19:03:28