使用Spring RestTemplate上传CommonsMultipartFile失败求助
使用RestTemplate上传MultipartFile到接收CommonsMultipartFile的服务
我看你正在尝试用RestTemplate上传文件到接收CommonsMultipartFile的Web服务,你的思路是对的——用ByteArrayResource来封装MultipartFile的字节数组,但核心的点是你没写完的getFilename重写方法,这是让服务端正确解析文件的关键。下面是完整的可运行代码和关键点说明:
完整实现代码
import org.springframework.core.io.ByteArrayResource; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.util.logging.Logger; public class FileUploadClient { private static final Logger logger = Logger.getLogger(FileUploadClient.class.getName()); public String upload(String uri, MultipartFile file) throws IOException { logger.info("URI: " + uri); // 封装文件为ByteArrayResource,必须重写getFilename方法 ByteArrayResource fileAsResource = new ByteArrayResource(file.getBytes()) { @Override public String getFilename() { // 返回原文件的文件名,服务端的CommonsMultipartFile需要这个来识别文件 return file.getOriginalFilename(); } }; // 构建multipart请求体:key要和服务端接口的参数名完全匹配 MultiValueMap<String, Object> requestBody = new LinkedMultiValueMap<>(); requestBody.add("file", fileAsResource); // 如果需要传递其他参数,直接添加即可 // requestBody.add("fileDesc", "这是一个测试上传文件"); // 设置请求头:必须指定为多部分表单类型 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); // 封装请求实体 HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers); // 调用RestTemplate发起请求(建议把RestTemplate作为Spring Bean注入,不要每次new) RestTemplate restTemplate = new RestTemplate(); String response = restTemplate.postForObject(uri, requestEntity, String.class); logger.info("Upload response: " + response); return response; } }
关键注意事项
- 必须重写
getFilename方法:ByteArrayResource本身没有文件名属性,而服务端的CommonsMultipartFile依赖文件名来完成初始化和解析,不重写的话服务端可能获取不到文件名,甚至直接解析失败。 - 请求体的key要严格匹配:
requestBody.add("file", ...)中的"file"必须和服务端接口的参数名一致,比如服务端代码如果是public String receiveFile(@RequestParam("file") CommonsMultipartFile file),这里的key就必须是"file"。 - 正确设置请求头:一定要把
ContentType设为MediaType.MULTIPART_FORM_DATA,否则服务端无法识别这是一个文件上传请求。 - RestTemplate的最佳实践:不要在方法内每次创建
RestTemplate实例,建议把它声明为Spring容器的Bean,通过@Autowired注入使用,避免资源浪费。
内容的提问来源于stack exchange,提问作者uncommon_breed
相关产品推荐
相关产品推荐

