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

Spring FeignClient多@RequestPart报错:Required part not present

解决Feign转发Multipart请求时DTO参数丢失问题

问题分析

你遇到的400错误提示Required part 'fileMetadataInDTO' is not present,核心原因是Feign的SpringFormEncoder默认不会将DTO对象以JSON格式封装到multipart请求的part中,导致后端无法识别该参数。

解决方案

方案1:给@RequestPart指定Content-Type

直接在FeignClient的@RequestPart注解中显式指定DTO的Content-Type为application/json,让Feign正确编码该参数:

@FeignClient(
        name = "file-upload-client", url = "${manager.root.uri}", configuration = BackendFeignClient.MultipartSupportConfig.class)
public interface BackendFeignClient
{
    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    ResponseEntity<FileMetadataOutDTO> save(
            // 显式指定DTO的Content-Type为JSON
            @RequestPart(value = "fileMetadataInDTO", contentType = MediaType.APPLICATION_JSON_VALUE) FileMetadataInDTO fileMetadataInDTO,
            @RequestPart("file") MultipartFile file,
            @RequestHeader(HttpHeaders.AUTHORIZATION) String jwtToken);

    class MultipartSupportConfig {
        @Autowired
        private ObjectFactory<HttpMessageConverters> messageConverters;

        @Bean
        public Encoder feignFormEncoder () {
            return new SpringFormEncoder(new SpringEncoder(messageConverters));
        }
    }
}

方案2:自定义SpringFormEncoder全局处理DTO编码

如果需要全局适配这类多参数multipart请求场景,可以自定义Encoder继承SpringFormEncoder,自动为非文件类型参数设置JSON格式:

public class CustomFormEncoder extends SpringFormEncoder {

    public CustomFormEncoder(Encoder delegate) {
        super(delegate);
        addConverter(new SpringEncoder.ObjectWrapperEncoder());
    }

    @Override
    public void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException {
        // 处理单个DTO参数的场景,包装为Map并指定格式
        if (bodyType != null && !bodyType.equals(MultipartFile.class) && !isMultipartFileCollection(object)) {
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("fileMetadataInDTO", object);
            super.encode(paramMap, MAP_STRING_WILDCARD, template);
            template.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE);
            return;
        }
        super.encode(object, bodyType, template);
    }

    private boolean isMultipartFileCollection(Object object) {
        if (object instanceof Collection) {
            Collection<?> collection = (Collection<?>) object;
            return collection.stream().allMatch(item -> item instanceof MultipartFile);
        }
        return false;
    }
}

然后在Feign配置类中替换为自定义Encoder:

class MultipartSupportConfig {
    @Autowired
    private ObjectFactory<HttpMessageConverters> messageConverters;

    @Bean
    public Encoder feignFormEncoder () {
        return new CustomFormEncoder(new SpringEncoder(messageConverters));
    }
}

额外注意事项

  1. 依赖版本匹配:确保feign-form和feign-form-spring版本与Spring Boot版本兼容,比如Spring Boot 2.x对应feign-form3.x版本,Spring Boot 3.x对应4.x版本。
  2. 后端接口笔误修正:你的后端接口中fileService.save(calibrationCertificateInDTO, file)应改为fileService.save(fileMetadataInDTO, file),避免后续业务逻辑报错。
  3. 参数名一致性:确认FeignClient与后端接口的@RequestPart的value完全一致(当前代码已满足)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 20:13:13