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

Java中如何通过REST API发送MultipartFile及附带参数

Java: Upload MultipartFile with Extra Parameters via REST API

Got it, let's break down how to send a MultipartFile along with your required/optional parameters to that target REST API. Below are two practical implementations using Spring's most common HTTP clients:


1. Using RestTemplate (Synchronous Approach)

This is ideal if you're working with a traditional Spring MVC application.

Step 1: Configure RestTemplate

First, make sure your RestTemplate is set up to handle multipart requests properly:

@Configuration
public class RestTemplateConfig {
    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        FormHttpMessageConverter multipartConverter = new FormHttpMessageConverter();
        multipartConverter.setMultipartCharset(StandardCharsets.UTF_8);
        restTemplate.getMessageConverters().add(multipartConverter);
        return restTemplate;
    }
}

Step 2: Implement the Upload Logic

Inject the RestTemplate into your service and build the multipart request:

@Service
public class FileUploadService {
    private final RestTemplate restTemplate;

    // Constructor injection (preferred over field injection)
    public FileUploadService(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    public ModelAndView uploadFile(MultipartFile file, 
                                   String wfid, 
                                   String ssoToken, 
                                   String typeMedia, 
                                   String synopsisParam, 
                                   String slideShowParam) throws IOException {
        // Build the multipart request body
        MultiValueMap<String, Object> requestBody = new LinkedMultiValueMap<>();
        
        // Add the file: Replace "file" with the actual @RequestParam name from your target API
        requestBody.add("file", new ByteArrayResource(file.getBytes()) {
            @Override
            public String getFilename() {
                return file.getOriginalFilename(); // Critical: Filename must be set for backend to recognize the file
            }
        });

        // Add optional parameters only if they're not null
        Optional.ofNullable(wfid).ifPresent(val -> requestBody.add("wfid", val));
        // ssoToken is required, so we add it directly
        requestBody.add("ssoToken", ssoToken);
        Optional.ofNullable(typeMedia).ifPresent(val -> requestBody.add("typeMedia", val));
        Optional.ofNullable(synopsisParam).ifPresent(val -> requestBody.add("synopsisParam", val));
        Optional.ofNullable(slideShowParam).ifPresent(val -> requestBody.add("slideShowParam", val));

        // Set headers (RestTemplate auto-handles multipart/form-data content type)
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);

        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);

        // Send the POST request: Replace with your actual API URL
        String targetApiUrl = "http://your-server-domain.com/file";
        return restTemplate.postForObject(targetApiUrl, requestEntity, ModelAndView.class);
    }
}

2. Using WebClient (Reactive Approach)

If you're using Spring WebFlux or prefer reactive programming, WebClient is the modern choice.

Step 1: Configure WebClient

@Configuration
public class WebClientConfig {
    @Bean
    public WebClient webClient() {
        return WebClient.builder()
                .baseUrl("http://your-server-domain.com") // Set base URL for your target API
                .build();
    }
}

Step 2: Implement Reactive Upload Logic

@Service
public class ReactiveFileUploadService {
    private final WebClient webClient;

    public ReactiveFileUploadService(WebClient webClient) {
        this.webClient = webClient;
    }

    public Mono<ModelAndView> uploadFile(MultipartFile file, 
                                         String wfid, 
                                         String ssoToken, 
                                         String typeMedia, 
                                         String synopsisParam, 
                                         String slideShowParam) throws IOException {
        return webClient.post()
                .uri("/file") // Relative path (uses base URL from config)
                .contentType(MediaType.MULTIPART_FORM_DATA)
                .body(BodyInserters.fromMultipartData(buildMultipartBody(file, wfid, ssoToken, typeMedia, synopsisParam, slideShowParam)))
                .retrieve()
                .bodyToMono(ModelAndView.class)
                .onErrorResume(e -> {
                    // Handle errors (e.g., HTTP 4xx/5xx) here
                    return Mono.error(new RuntimeException("Upload failed: " + e.getMessage()));
                });
    }

    private MultiValueMap<String, Object> buildMultipartBody(MultipartFile file, 
                                                            String wfid, 
                                                            String ssoToken, 
                                                            String typeMedia, 
                                                            String synopsisParam, 
                                                            String slideShowParam) throws IOException {
        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
        
        // Add file (again, match the @RequestParam name from the target API)
        body.add("file", new ByteArrayResource(file.getBytes()) {
            @Override
            public String getFilename() {
                return file.getOriginalFilename();
            }
        });

        // Add parameters
        Optional.ofNullable(wfid).ifPresent(val -> body.add("wfid", val));
        body.add("ssoToken", ssoToken);
        Optional.ofNullable(typeMedia).ifPresent(val -> body.add("typeMedia", val));
        Optional.ofNullable(synopsisParam).ifPresent(val -> body.add("synopsisParam", val));
        Optional.ofNullable(slideShowParam).ifPresent(val -> body.add("slideShowParam", val));

        return body;
    }
}

Key Notes to Remember

  • Parameter Name Matching: Double-check that the parameter names you use in requestBody.add(...) exactly match the @RequestParam names in the target API (including case sensitivity, though most servers are lenient, it's best to be precise).
  • Filename Requirement: Always override getFilename() for the ByteArrayResource—without this, the backend may not recognize the file part correctly.
  • Error Handling: Add try-catch blocks for RestTemplate or use onErrorResume for WebClient to handle HTTP errors, timeouts, or file read issues.
  • Large Files: For large file uploads, adjust the timeout settings in RestTemplate or WebClient to avoid request failures.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 02:23:58