问题 使用FeignClient上传文件时居然失败了?意外,不敢相信SpringCloud中的组件不可能不支持该功能 版本 SpringCloud: Dalston.Release feign: 9.4.0
期间有各种报错,如: FileUploadException: the request was rejected because no multipart boundary was found MissingServletRequestPartException: Required request part ‘file’ is not present
原因 因为feign 9.4.0默认并不支持multipart/form(文件上传),需要手动引入feign-form、feign-form-spring
使用方式 引入feign-form依赖
1 2 3 4 5 6 7 8 9 10 11 12 <dependencies > <dependency > <groupId > io.github.openfeign.form</groupId > <artifactId > feign-form</artifactId > <version > 3.3.0</version > </dependency > <dependency > <groupId > io.github.openfeign.form</groupId > <artifactId > feign-form-spring</artifactId > <version > 3.3.0</version > </dependency > </dependencies >
改造上传文件FeignClient
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @FeignClient ( name = "file-upload-service" , configuration = FileUploadServiceClient.MultipartSupportConfig.class ) public interface FileUploadServiceClient extends IFileUploadServiceClient { public class MultipartSupportConfig { @Autowired private ObjectFactory<HttpMessageConverters> messageConverters; @Bean public Encoder feignFormEncoder () { return new SpringFormEncoder(new SpringEncoder(messageConverters)); } } }
到此已可用
不同版本选择 上文中采用的feign-form版本是与feign版本是对应的。如果版本对应错误,是不兼容的。
spring-cloud
feign
feign-form
Dalston
9.4.0
3.5.0以前(20191122最新:3.4.1)
Greenwich
10.4.0
3.5.0以后(20191122最新:3.8.0)
MultipartFile接收时找不到问题 MissingServletRequestPartException: Required request part ‘file’ is not present 正常情况下可能是指定的文件名不对,其它的可能不谈,只谈我在使用过程中遇到问题 用户端: 上传文件 Server1: 接收用户上传文件 Server2: 接收服务器端1上传文件 1、Server2代码示例
1 2 3 4 5 6 @RequestMapping (value = "upload" , method = RequestMethod.POST, consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}) @ResponseBody public void checkin(@RequestPart ("file" ) MultipartFile file) { }
2、Server1代码示例
1 2 3 4 5 6 7 @RequestMapping (value = "upload" , method = RequestMethod.POST, consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}) @ResponseBody public RespBody checkin(@RequestPart ("file1" ) MultipartFile file1) { Server2FeignClient .upload (file1); return RespBody .ok (); }
Server2FeignClient关键代码
1 void upload (@RequestPart ("file" ) MultipartFile file);
结果就是Server2可以接收到请求,但是收不到file文件,此时我们查看Server1中的MultipartFile对象发现,虽然已经在Server2FeignClient中设置MultipartFile 的key为file,但是Server2收到的仍然是file1。
解决方法: 通过反映方式将MultipartFile的fieldName改为Server2需要的key
1 2 3 4 5 6 7 Field partField = multipartFile.getClass() .getDeclaredField("part" ) ; partField.setAccessible(true ) ; ApplicationPart part = (ApplicationPart) partField.get(multipartFile); Field fileItemField = part.getClass() .getDeclaredField("fileItem" ) ; fileItemField.setAccessible(true ) ; org.apache.tomcat.util.http.fileupload.disk.DiskFileItem fileItem = (org.apache.tomcat.util.http.fileupload.disk.DiskFileItem) fileItemField.get(part); fileItem.setFieldName("file" ) ;
引用 https://github.com/OpenFeign/feign-form