Spring Boot Rest Api - 多个 @RequestPart 不适用于 Feign 客户端

发布时间:2021-03-02 12:45

我有一个 Spring Boot 2.4.3

@RestController
public class DemoFeignController {
    @PutMapping(value = "/document", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public String upload(@RequestPart("file") MultipartFile multipartFile,
                         @RequestPart("config") String config) {
        System.out.println(multipartFile.getSize());
        System.out.println("config:" + config);
        return "upload";
    }
    @PutMapping(value = "/document2", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public String upload2(@RequestPart("file") MultipartFile multipartFile,
                         @RequestPart("config") DocumentConfiguration documentConfiguration) {
        System.out.println(multipartFile.getSize());
        System.out.println("config2:" + documentConfiguration);
        return "upload2";
    }
}

我也有

@Component
public class DemoFeignServiceAdapter extends WebMvcConfigurerAdapter {
    @Autowired
    DemoFeignServiceInterceptor filetnetServiceInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(filetnetServiceInterceptor);
    }
}

@Component
public class DemoFeignServiceInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("Pre Handle http request");
        request.getParts().stream()
                .forEach(part -> {
                    System.out.println(part.getName());
                });
        return true;
    }
}

最终

@数据 公共类文档配置{ 私人字符串名称; 私有字符串类型; }

如果我用 Postman 调用这 2 个端点,它就可以工作了。

enter image description here

调用/upload和/upload2,我可以在日志中看到

Pre Handle http request
file
config
1161530
config:{"name": "my-document", "type": "pdf"}
Pre Handle http request
file
config
1161530
config2:DocumentConfiguration(name=my-document, type=pdf)

config2:DocumentConfiguration(name=my-document, type=pdf)

现在有了 Feign 客户端

@FeignClient(name = "demo-service", url = "http://localhost:8090")
public interface DemoFeignProxy {
    @PutMapping(value = "/document", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    String upload(@RequestPart("file") MultipartFile multipartFile,
                         @RequestPart("config") String config);
    @PutMapping(value = "/document2", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    String upload2(@RequestPart("file") MultipartFile multipartFile,
                          @RequestPart("config") DocumentConfiguration documentConfiguration);
}

@SpringBootTest
class DemoFeignApplicationTests {
    @Autowired
    DemoFeignProxy demoFeignProxy;
    @Test
    void upload() {
        byte[] file = "Hello world".getBytes(StandardCharsets.UTF_8);
        MultipartFile multipartFile = new MockMultipartFile("file", "temp", "text/plain", file);
        System.out.println(demoFeignProxy.upload(multipartFile, "my-config"));
    }
    @Test
    void upload2() {
        byte[] file = "Hello world".getBytes(StandardCharsets.UTF_8);
        MultipartFile multipartFile = new MockMultipartFile("file", "temp", "text/plain", file);
        DocumentConfiguration documentConfiguration = new DocumentConfiguration();
        documentConfiguration.setName("my-config");
        documentConfiguration.setType("pdf");
        System.out.println(demoFeignProxy.upload2(multipartFile, documentConfiguration));
    }
}

上传成功。

Pre Handle http request
file
config
11
config:my-config

但是对于upload2,它不起作用

Pre Handle http request
file
name
type
2021-03-02 13:39:05.850  WARN 20836 --- [nio-8090-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : 
Resolved [org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'config' is not present]

我不明白为什么我有名称和类型而不是配置。

因为 Postman 没问题,所以我想问题出在 Feign 客户端上。 但我不知道我错过了什么。

编辑:

调用 http://127.0.0.1:8090/swagger-ui/index.html 我也有例外

javax.servlet.ServletException: org.apache.tomcat.util.http.fileupload.impl.InvalidContentTypeException: the request doesn't contain a multipart/form-data or multipart/mixed stream, content type header is null
回答1