在使用 Spring 的 RestTemplate 来发送 multipart/form-data 请求时,特别是当你需要手动设置 Content-Type 边界(boundary)时,有一些特定的步骤需要遵循。通常,当使用 MultipartResolver 或类似的机制时,Spring 会自动处理这些内容,但有时你可能需要手动控制这些细节。
以下是如何配置 RestTemplate 以支持带有自定义 boundary 的 multipart/form-data:
创建 RestTemplate 实例:
确保你的 RestTemplate 实例已经配置好了必要的消息转换器,通常 Spring 的默认配置已经足够。但如果你有特殊的配置需求,可以自定义消息转换器。
使用 MultipartResolver 构建请求体:
使用 MockMvc 或者直接构建 MultipartFile 和其他表单数据,然后通过 FormHttpMessageConverter 来序列化这些数据。
设置 HttpHeaders:
手动设置 Content-Type 头,包括计算的 boundary。
发送请求:
使用 RestTemplate 发送请求。
下面是一个具体的示例:
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class RestTemplateMultipartExample {
public static void main(String[] args) throws IOException {
RestTemplate restTemplate = new RestTemplate();
// 添加 FormHttpMessageConverter(如果默认没添加的话)
restTemplate.getMessageConverters().add(new FormHttpMessageConverter());
// 创建 MultiValueMap 来存储表单数据
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
// 添加文件部分
ClassPathResource resource = new ClassPathResource("testfile.txt");
MultipartFile file = new CommonsMultipartFile("file",
resource.getFilename(), "text/plain", resource.getInputStream());
body.add("file", file);
// 添加其他字段
body.add("description", "This is a test file");
// 设置 Headers
HttpHeaders headers = new HttpHeaders();
String boundary = "----WebKitFormBoundary7MA4YWxkTrZu0gW"; // 自定义 boundary
MediaType mediaType = MediaType.MULTIPART_FORM_DATA;
mediaType = MediaType.valueOf(mediaType + "; boundary=" + boundary);
headers.setContentType(mediaType);
// 使用 HttpEntity 包装请求体和头
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
// 发送 POST 请求
String response = restTemplate.postForObject("http://example.com/upload", requestEntity, String.class);
System.out.println(response);
}
}