在使用 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);
    }
}