写于:2019-10-09 22:52:37

更新于 2020-04-19 基于Spring Cloud Greenwich.SR1 不需要手动引入 feign-formspring-cloud-starter-openfeign 已经集成有该模块。

相关版本:Spring Boot 2.1.4.RELEASE 、Spring Cloud Greenwich.SR open-feign 版本:10.1.0 feign-form 版本:3.8.0

code.zip

一、开发场景

存在服务A 和 服务B ,服务 A 与 服务 B 通过 Feign 进行远程服务调用。

需求:服务 A 接收文件流,通过调用 服务 B 进行文件的上传。

二、解决

feign-form Github

Feign 提供了扩展插件 feign-form 实现了 Feign 的文件上传。

在使用 feign-form 时候需要注意版本问题,来看看官方的说法:

  • all feign-form releases before 3.5.0 works with OpenFeign 9.* versions;
  • starting from feign-form’s version 3.5.0, the module works with OpenFeign 10.1.0 versions and greater.

翻译如下:

  • 所有 feign-form 3.5.0 之前的稳定版本,能够运行在 open-feign 9.X 版本之上
  • 从 feign-form 3.5.0 之后的版本,能够运行在 open-feign 10.1.0 版本之上

三、代码实现

工程

服务名称 服务名称 实现逻辑
feign-api 暴露调用接口
feign-consumer 9527 接收文件流,并传递给 feign-provider
feign-provider 9528 实现文件上传功能
feign-register 1111 注册中心

feign-consumer

进行文件流的接收,通过 Feign 实现文件流的传递

引入 feign-form依赖

  1. <!-- feign form -->
  2. <dependency>
  3. <groupId>io.github.openfeign.form</groupId>
  4. <artifactId>feign-form</artifactId>
  5. <version>3.8.0</version>
  6. </dependency>
  7. <!--
  8. <groupId>io.github.openfeign.form</groupId>
  9. <artifactId>feign-form-spring</artifactId>
  10. -->

除了 feign-form 依赖之外,还需要引入 feign-form-spring ,不过项目中引入了 spring-cloud-starter-openfeign ,而该模块默认引入了 feign-form-spring

Controller 入口代码

  1. @RestController
  2. public class FeignUploadController {
  3. @Autowired
  4. private FeignUploadClient feignUploadClient;
  5. // 经过验证参数的接收:使用 @RequestParam,@RequestPart,或者不加都可以
  6. @RequestMapping(value = "/consumer/single/upload3",method = RequestMethod.POST)
  7. public String singleUpload3( MultipartFile file) throws IOException {
  8. return feignUploadClient.singleUpload(file);
  9. }
  10. }

经过验证,这里参数 MultipartFile 的接收,使用 @RequestParam ,@RequestPart,或者不添加都可以。

远程服务调用 FeignClient 代码

  1. @FeignClient(name = "provider")
  2. public interface FeignUploadClient extends IFeignUploadController {
  3. }

feign-api

暴露 feign-provider 的API

上传 API 接口

  1. public interface IFeignUploadController {
  2. /**
  3. * <p> 单文件上传 </p>
  4. *
  5. * @param file 文件流
  6. * @return
  7. */
  8. @RequestMapping(value = "/provider/single/upload",method = RequestMethod.POST,consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
  9. String singleUpload(MultipartFile file) throws IOException;
  10. }

重点:这里的 consumes = MediaType.MULTIPART_FORM_DATA_VALUE 一定要指定

feign-provider

接收文件流,进行文件上传操作

Controller 代码

  1. @RestController
  2. public class FeignUploadController implements IFeignUploadController {
  3. @Override
  4. @RequestMapping(value = "/provider/single/upload",method = RequestMethod.POST)
  5. public String singleUpload(MultipartFile file) throws IOException {
  6. // TODO other operate
  7. return file.getOriginalFilename();
  8. }
  9. }

四、总结

引入 feign-form 依赖

在 feign client 调用的 API 中 consumes = MediaType.MULTIPART_FORM_DATA_VALUE