在多数时候,我们都会遇见两个系统间传递文件的需求,对于这种文件传输,在之前单体应用/部署在同一台机子的时候比较好处理。
但是如今在微服务的时代,不同业务拆分成不同的模块系统,同时有可能部署在不同的服务器上,这时候要进行两个服务间传输文件就会相对困难,但并不是没有解决方案:
- 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
推荐阅读: