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

Spring Boot服务转发Multipart请求时客户端连接终止问题排查

问题解决:Spring Boot转发Multipart请求到Quarkus时连接终止

出现Connection terminated parsing multipart request错误的核心原因通常是:

  • 手动设置的Content-Length值与实际请求体大小不匹配,导致服务端读取时提前断开连接
  • 手动设置的Content-Type缺少multipart请求必需的boundary参数,服务端无法正确解析请求
  • 文件流处理不当(比如提前关闭),导致请求体未完整发送

以下是具体修改建议:

修改方案1:移除手动设置的Content-Length

手动计算Content-Length容易出错,尤其是处理文件流时,RestTemplate会自动根据请求体生成正确的Content-Length,无需手动设置。

修改方案2:正确构建Multipart请求体

使用Spring提供的InputStreamResource包装MultipartFile的流,确保文件名被正确传递,同时避免流提前关闭的问题。

修改方案3:不要手动设置完整的Content-Type

直接设置MediaType.MULTIPART_FORM_DATA即可,RestTemplate会自动添加随机生成的boundary参数,这是multipart请求解析的必需项。


修改后的uploadFiles方法

private String uploadFiles(MultipartFile file) {
    try {
        // 构建multipart请求体
        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
        // 使用InputStreamResource包装文件流,确保文件名正确传递
        body.add("field2", new InputStreamResource(file.getInputStream()) {
            @Override
            public String getFilename() {
                return file.getOriginalFilename();
            }
        });

        HttpHeaders headers = new HttpHeaders();
        // 仅指定MediaType,RestTemplate会自动添加boundary
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);

        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
        ResponseEntity<FileUploadResponse> uploadResponse = rt.postForEntity("http://localhost:8080/upload", requestEntity, FileUploadResponse.class);

        if (uploadResponse.getStatusCode().is2xxSuccessful()) {
            return Objects.requireNonNull(uploadResponse.getBody()).fileName();
        } else {
            throw new FileUploadFailed("Storage Engine returned error response");
        }
    } catch (IOException e) {
        throw new FileUploadFailed("could not retrieve file size of the attached file", e);
    }
}

额外检查:确保RestTemplate配置正确

如果是自定义RestTemplate实例,需要确保添加了MultipartFormHttpMessageConverter(Spring Boot默认配置已包含,但自定义时需确认):

@Bean
public RestTemplate restTemplate() {
    RestTemplate restTemplate = new RestTemplate();
    // 添加multipart消息转换器
    restTemplate.getMessageConverters().add(new MultipartFormHttpMessageConverter());
    return restTemplate;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 14:38:17