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

Spring RestTemplate调用时自定义请求/响应对象能否携带MultipartFile

问题结论

你提到的两个需求都可以通过Spring RestTemplate实现,当前报错是因为multipart表单构造方式错误、拼写错误共同导致的。

上传场景实现(问题1解决方案)

错误原因

你直接将包含MultipartFile的自定义UploadRequest对象作为整体放入MultiValueMap中,RestTemplate会尝试用Jackson序列化整个Java Bean,而MultipartFile内部包含FileDescriptor、IO流这类无法序列化的属性,就会抛出你遇到的序列化异常。此外你代码里的Content-Type拼写错误(将multipart写为mutipart)也会导致请求格式识别失败。

正确实现代码

不需要修改自定义的UploadRequest类,只需要调整表单构造逻辑,把对象属性平铺开放入表单即可,Spring接收端会自动完成参数绑定:

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);

MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
// 拆分UploadRequest属性放入表单
form.add("checkSum", uploadRequest.getCheckSum());
// MultipartFile需要转成Resource再放入表单,RestTemplate可直接识别处理
form.add("fileContents", uploadRequest.getFileContents().getResource());

HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(form, headers);
ResponseEntity<UploadResponse> responseEntity = restTemplate.postForEntity(uploadUrl, requestEntity, UploadResponse.class);

接收端接口直接用@ModelAttribute UploadRequest uploadRequest即可正常接收所有参数。

下载场景实现(问题2解决方案)

不能直接在自定义响应类中声明MultipartFile属性自动接收,需要先解析响应的multipart内容,再手动组装到自定义对象中。

实现步骤

  1. 先给RestTemplate配置支持解析multipart响应的消息转换器:
restTemplate.getMessageConverters().add(new FormHttpMessageConverter());
  1. 调用接口后先解析为通用的multipart结构,再手动组装自定义响应对象:
// 声明响应类型为MultiValueMap
ResponseEntity<MultiValueMap<String, Object>> resp = restTemplate.exchange(
    downloadUrl,
    HttpMethod.GET,
    requestEntity,
    new ParameterizedTypeReference<MultiValueMap<String, Object>>() {}
);

MultiValueMap<String, Object> respBody = resp.getBody();
// 手动组装自定义响应对象
DownloadResponse downloadResponse = new DownloadResponse();
// 读取普通属性
downloadResponse.setCheckSum((Long) respBody.getFirst("checkSum"));
downloadResponse.setRemark((String) respBody.getFirst("remark"));
// 读取文件资源,可按需转为MultipartFile
Resource fileResource = (Resource) respBody.getFirst("fileContents");
// 如需转为MultipartFile,可借助MockMultipartFile(需引入spring-test依赖)或自行实现MultipartFile接口
MultipartFile file = new MockMultipartFile(
    "fileContents", 
    fileResource.getFilename(), 
    MediaType.APPLICATION_OCTET_STREAM_VALUE, 
    fileResource.getInputStream()
);
downloadResponse.setFileContents(file);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 23:36:00