Spring RestTemplate跨微服务传视频文件序列化异常修复
问题产生原因
报错的核心原因是App A转发文件时的参数传递逻辑错误:
- 你直接将Spring MVC接收到的
MultipartFile实例放入RestTemplate的请求体中,RestTemplate默认使用Jackson对请求内的Java对象做序列化处理 MultipartFile是Spring针对服务端接收上传文件封装的对象,内部持有FileInputStream、FileDescriptor这类和本地操作系统文件句柄绑定的资源属性,这类属性没有可供Jackson序列化的字段,也无法被序列化成网络传输的内容,最终触发序列化失败异常。
修复方案
不要直接传递MultipartFile对象,将文件内容转换为Spring支持的Multipart资源类型后再放入请求体,RestTemplate会自动按form-data的二进制流规则组装请求,不会触发Jackson对象序列化逻辑。
具体修改步骤
- 修改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(); } }
- (可选优化)如果传输的视频文件体积较大,为了避免全量读入字节数组占用过高内存,可以将
MultipartFile转为临时文件后用FileSystemResource传递,示例代码片段:
// 大文件传输替换逻辑 File tempFile = File.createTempFile("upload-", file.getOriginalFilename()); file.transferTo(tempFile); body.add("file", new FileSystemResource(tempFile)); // 请求完成后记得删除临时文件避免磁盘占用 tempFile.deleteOnExit();
- (额外问题修正)你当前
AppAController的依赖注入写法存在语法错误,@Autowired标注在final字段上无法完成注入,建议改成构造器注入,或者移除字段的final修饰,该问题不影响本次序列化报错,但会导致应用启动失败。
修改完成后重启App A,再通过Postman发送请求即可正常完成文件转发,App B可以正常接收到视频文件并执行关键帧提取逻辑。
内容的提问来源于stack exchange,提问作者TaeXtreme
相关产品推荐
相关产品推荐

