OpenFeign传输文件MultipartFile
文件发送方
1.OpenFeign默认不支持文件上传,需要通过引入Feign的扩展包来实现,添加依赖
文件上传方需要添加如下依赖:
<dependency> <groupId>io.github.openfeign.form</groupId> <artifactId>feign-form</artifactId> <version>3.8.0</version> </dependency> <dependency> <groupId>io.github.openfeign.form</groupId> <artifactId>feign-form-spring</artifactId> <version>3.8.0</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.3</version> </dependency> </dependencies>
并且添加如下配置类:
@Configuration public class FeignConfiguration { @Autowired private ObjectFactory<HttpMessageConverters> messageConverters; @Bean public Encoder feignEncoder() { return new SpringFormEncoder(new SpringEncoder(messageConverters)); } }
person类:
@Data public class Person { private String name; private Integer age; }
测试页面:index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/hello/test" method="post" enctype="multipart/form-data"> <input type="text" name="name"> <input type="text" name="age"> <input type="file" name="file"> <br> <div>上传文件:<input type="file" name="file2" multiple="multiple"></div> <input type="submit" value="Submit"> </form> </body> </html>
controller:
@RestController @RequestMapping("/hello") public class HelloController { @Autowired private Client2FeignService client2FeignService; @PostMapping("/test") public String test(@RequestParam(value = "file")MultipartFile file, @RequestParam(value = "file2")MultipartFile[] files,Person person) { return client2FeignService.test(file, files, person.getAge(), person.getName()); } }
Client2FeignService接口:
注意:
PostMapping
注解的consumes
要设置成MediaType.MULTIPART_FORM_DATA_VALUE
,不然会直接报错MultipartFile
类型前面用@RequestPart
注解修饰,不然文件会传输不过去
@FeignClient("client2") public interface Client2FeignService { @PostMapping(value = "/hello/test",consumes = MediaType.MULTIPART_FORM_DATA_VALUE) String test(@RequestPart(value = "file") MultipartFile file, @RequestPart(value = "file2")MultipartFile[] files, @RequestParam("age") Integer age, @RequestParam("name") String name); }
文件接收方
controller:
@RestController @RequestMapping("/hello") public class HelloController { @PostMapping("/test") String test(@RequestPart(value = "file") MultipartFile file, @RequestPart(value = "file2")MultipartFile[] files, @RequestParam("age") Integer age, @RequestParam("name") String name) { System.out.println(age); System.out.println(name); System.out.println(file.getSize()); for (MultipartFile multipartFile : files) { System.out.println(multipartFile.getSize()); } return "ok"; } }
测试
我这里:file参数只有一个文件,file2参数我上传了两个文件
查看文件接收方的输出:
单文件、多文件和其他普通参数都可以发送。
那这里name
和age
为什么要拆开来传输,而不直接传输Person
实体类呢?
因为使用Person
会直接报错,我目前没有找到好的办法。
那有人会问,如果实体类有很多字段怎么办,一个一个拿出来作为方法参数传过去吗?
当然不用,直接文件发送方把实体类转成json字符串,然后接收方再反序列化回来不就行了吗。
补充-2022/03/07
openfeign同时传输文件和实体类:
文件发送方:
@PostMapping("/test") public String test(@RequestParam(value = "file")MultipartFile file, @RequestParam(value = "file2")MultipartFile[] files,Person person) { return client2FeignService.test(file, files, person); } @FeignClient("client2") public interface Client2FeignService { @PostMapping(value = "/hello/test",consumes = MediaType.MULTIPART_FORM_DATA_VALUE) String test(@RequestPart(value = "file") MultipartFile file, @RequestPart(value = "file2")MultipartFile[] files, @SpringQueryMap Person person); }
文件接收方:
@PostMapping("/test") String test(@RequestPart(value = "file") MultipartFile file, @RequestPart(value = "file2")MultipartFile[] files, Person person) { System.out.println(person); System.out.println(file.getSize()); for (MultipartFile multipartFile : files) { System.out.println(multipartFile.getSize()); } return "ok"; }