Feign微服务间通过@RequestBody进行文件传输

在多数时候,我们都会遇见两个系统间传递文件的需求,对于这种文件传输,在之前单体应用/部署在同一台机子的时候比较好处理。

但是如今在微服务的时代,不同业务拆分成不同的模块系统,同时有可能部署在不同的服务器上,这时候要进行两个服务间传输文件就会相对困难,但并不是没有解决方案:

  • 1、采用oss存储作为唯一媒介,将文件上传到oss上,然后再进行获取
  • 2、使用feign的直接传输,但是必须得引入 feign-form 来进行传输
  • 3、就是写一个Encoder解析器

上面介绍的这几种相对来说比较复杂,但都是可以解决微服务系统间文件传输的问题。而今天我们要介绍的另外一种方案就是直接将文件转为byte,通过普通的@RequestBody形式(即json格式)进行文件传输,该方案可能不太适用于更复杂的场景,但也是笔者在写代码时候发现的另一种方法。

二、具体实现

1、本文将介绍使用feign从spring-feign-demo1 以 json形式传递文件到spring-feign-demo2的关键性代码

在spring-cloud-demo2中编写用于接收文件的DTO和Controller。

1、Controller层

@Controller
public class FeignController {

    /**
     * 接收文件
     */
    @RequestMapping(value = "/feign/send/file", method = {RequestMethod.POST})
    @ResponseBody
    public String performController(@RequestBody FeignRequestDTO requestDTO) {
        try {
            // 将demo1的文件流保存到该服务器的指定目录下
            // 注意:文件名和格式可以通过请求参数定义一个字段传输,这里不做演示
            File file = new File("D:\\demo2\\新demo1的文件.xlsx");
            FileUtils.writeByteArrayToFile(file,requestDTO.getFile());
            System.out.println("成功接收来自demo1的文件");
            // todo 读取demo2服务器的文件继续业务处理即可
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "true";
    }

2、demo2的RequestDTO请求对象如下

public class FeignRequestDTO {

    /**
     * 用户编号
     */
    private String userId;

    public String getUserId() {return userId;}

    public void setUserId(String userId) { this.userId = userId;}

    /**
     * 用户名
     */
    private String userName;

    public String getUserName() { return userName;}

    public void setUserName(String userName) {this.userName = userName;}

    /**
     * 文件流(关键字段)
     */
    private byte[] file;

    public byte[] getFile() {return file;}

    public void setFile(byte[] file) {this.file = file;}
}

在spring-cloud-demo1中编写调用Demo2的Feign接口并调用。

1、Feign接口

@Component
@FeignClient(name = "spring-cloud-demo2")
public interface FeignDemo2Interface {

  /**
   * feign的对外接口请求方法
   *
   * @param requestDTO
   * @return
   */
  @RequestMapping(value = "/feign/send/file", method = {RequestMethod.POST})
  @ResponseBody
  String performController(@RequestBody FeignRequestDTO requestDTO);

}

2、demo1中的发送文件到的demo2的Controller

@Controller
public class FeignDemo1Controller {


    @Autowired
    private FeignDemo2Interface feignDemo2Interface;

    /**
     * 处理请求
     */
    @RequestMapping(value = "/feign/demo1/test", method = {RequestMethod.GET})
    @ResponseBody
    public void performController() {
        try {
            // 读取该服务器本地的文件并转换为byte
          byte[] bytes = FileUtils.readFileToByteArray(new File("D:\\demo1\\demo1的文件.xlsx"));
          // 引用demo2的对象将读取的文件进行封装,并调用demo2的方法
            FeignRequestDTO requestDTO = new FeignRequestDTO();
            requestDTO.setUserId("10000");
            requestDTO.setUserName("张三");
            requestDTO.setFile(bytes);
          String s = feignDemo2Interface.performController(requestDTO);
          System.out.println("发送文件成功");

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

三、结果

1、调用demo1的controller后,即可将文件通过feign发送给demo2。
![image.png](https://upload-images.jianshu.io/upload_images/5134062-851c6c314199bfa4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

推荐阅读:

Spring Security系列教程

你可能感兴趣的:(Feign微服务间通过@RequestBody进行文件传输)