在多數時候,我們都會遇見兩個系統間傳遞文件的需求,對于這種文件傳輸,在之前單體應用/部署在同一臺機子的時候比較好處理。
但是如今在微服務的時代,不同業務拆分成不同的模塊系統,同時有可能部署在不同的服務器上,這時候要進行兩個服務間傳輸文件就會相對困難,但并不是沒有解決方案:
- 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
推薦閱讀: