在多數(shù)時(shí)候,我們都會(huì)遇見兩個(gè)系統(tǒng)間傳遞文件的需求,對(duì)于這種文件傳輸,在之前單體應(yīng)用/部署在同一臺(tái)機(jī)子的時(shí)候比較好處理。
但是如今在微服務(wù)的時(shí)代,不同業(yè)務(wù)拆分成不同的模塊系統(tǒng),同時(shí)有可能部署在不同的服務(wù)器上,這時(shí)候要進(jìn)行兩個(gè)服務(wù)間傳輸文件就會(huì)相對(duì)困難,但并不是沒有解決方案:
- 1、采用oss存儲(chǔ)作為唯一媒介,將文件上傳到oss上,然后再進(jìn)行獲取
- 2、使用feign的直接傳輸,但是必須得引入 feign-form 來進(jìn)行傳輸
- 3、就是寫一個(gè)Encoder解析器
上面介紹的這幾種相對(duì)來說比較復(fù)雜,但都是可以解決微服務(wù)系統(tǒng)間文件傳輸?shù)膯栴}。而今天我們要介紹的另外一種方案就是直接將文件轉(zhuǎn)為byte,通過普通的@RequestBody形式(即json格式)進(jìn)行文件傳輸,該方案可能不太適用于更復(fù)雜的場(chǎng)景,但也是筆者在寫代碼時(shí)候發(fā)現(xiàn)的另一種方法。
二、具體實(shí)現(xiàn)
1、本文將介紹使用feign從spring-feign-demo1 以 json形式傳遞文件到spring-feign-demo2的關(guān)鍵性代碼
在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的文件流保存到該服務(wù)器的指定目錄下
// 注意:文件名和格式可以通過請(qǐng)求參數(shù)定義一個(gè)字段傳輸,這里不做演示
File file = new File("D:\\demo2\\新demo1的文件.xlsx");
FileUtils.writeByteArrayToFile(file,requestDTO.getFile());
System.out.println("成功接收來自demo1的文件");
// todo 讀取demo2服務(wù)器的文件繼續(xù)業(yè)務(wù)處理即可
} catch (IOException e) {
e.printStackTrace();
}
return "true";
}
2、demo2的RequestDTO請(qǐng)求對(duì)象如下
public class FeignRequestDTO {
/**
* 用戶編號(hào)
*/
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;}
/**
* 文件流(關(guān)鍵字段)
*/
private byte[] file;
public byte[] getFile() {return file;}
public void setFile(byte[] file) {this.file = file;}
}
在spring-cloud-demo1中編寫調(diào)用Demo2的Feign接口并調(diào)用。
1、Feign接口
@Component
@FeignClient(name = "spring-cloud-demo2")
public interface FeignDemo2Interface {
/**
* feign的對(duì)外接口請(qǐng)求方法
*
* @param requestDTO
* @return
*/
@RequestMapping(value = "/feign/send/file", method = {RequestMethod.POST})
@ResponseBody
String performController(@RequestBody FeignRequestDTO requestDTO);
}
2、demo1中的發(fā)送文件到的demo2的Controller
@Controller
public class FeignDemo1Controller {
@Autowired
private FeignDemo2Interface feignDemo2Interface;
/**
* 處理請(qǐng)求
*/
@RequestMapping(value = "/feign/demo1/test", method = {RequestMethod.GET})
@ResponseBody
public void performController() {
try {
// 讀取該服務(wù)器本地的文件并轉(zhuǎn)換為byte
byte[] bytes = FileUtils.readFileToByteArray(new File("D:\\demo1\\demo1的文件.xlsx"));
// 引用demo2的對(duì)象將讀取的文件進(jìn)行封裝,并調(diào)用demo2的方法
FeignRequestDTO requestDTO = new FeignRequestDTO();
requestDTO.setUserId("10000");
requestDTO.setUserName("張三");
requestDTO.setFile(bytes);
String s = feignDemo2Interface.performController(requestDTO);
System.out.println("發(fā)送文件成功");
} catch (IOException e) {
e.printStackTrace();
}
}
三、結(jié)果
1、調(diào)用demo1的controller后,即可將文件通過feign發(fā)送給demo2。
![image.png](https://upload-images.jianshu.io/upload_images/5134062-851c6c314199bfa4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240
推薦閱讀: