spring cloud feign實(shí)現(xiàn)遠(yuǎn)程調(diào)用服務(wù)傳輸文件的方法
實(shí)踐案例包括兩個(gè)項(xiàng)目,服務(wù)提供者項(xiàng)目名:upload-service,調(diào)用服務(wù)項(xiàng)目名:upload-client,主要給出兩個(gè)服務(wù)之間的調(diào)用過程,文件上傳功能不提供
項(xiàng)目框架:spring-boot 2.0.1.RELEASE、spring-cloud Finchley.RELEASE
依賴:
<dependency> <groupId>io.github.openfeign.form</groupId> <artifactId>feign-form</artifactId> <version>3.0.3</version> </dependency> <dependency> <groupId>io.github.openfeign.form</groupId> <artifactId>feign-form-spring</artifactId> <version>3.0.3</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.3</version> </dependency>
// 申明這是一個(gè)Feign客戶端,并且指明服務(wù)id
@FeignClient(value = "com-spring-caclulate")
public interface CacluFeignClient {
// 這里定義了類似于SpringMVC用法的方法,就可以進(jìn)行RESTful的調(diào)用了
@RequestMapping(value = "/caclu/{num}", method = RequestMethod.GET)
public Item caclulate(@PathVariable("num") Integer num);
}
一.文件上傳服務(wù)upload-service
1.控制層
@Slf4j
@CrossOrigin
@RestController
@RequestMapping("/ftp")
@Api(description = "文件上傳控制")
public class FtpFileController {
@Autowired
private FtpFileService ftpFileService;
/**
* FTP文件上傳
*
* @return
*/
@PostMapping(value = "/uploadFile", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public FtpApiResponse<FtpUploadResDTO> uploadFileFTP(@RequestPart(value = "file") MultipartFile file,
@RequestParam("logId") String logId) {
FtpApiResponse<FtpUploadResDTO> result = new FtpApiResponse<>();
LogUtil.updateLogId(logId);
try {
log.info("文件上傳開始!}");
Long startTime = System.currentTimeMillis();
FtpUploadResDTO resDTO = ftpFileService.uploadFile(file);
result.setData(resDTO);
result.setSuccess(true);
result.setTimeInMillis(System.currentTimeMillis() - startTime);
log.info("文件上傳結(jié)束 resDTO:{},耗時(shí):{}", resDTO, (System.currentTimeMillis() - startTime));
} catch (ServiceException e){
result.setSuccess(false);
result.setErrorCode(ErrorMsgEnum.FILE_UPLOAD_EXCEPTION.getCode());
result.setErrorMsg(ErrorMsgEnum.FILE_UPLOAD_EXCEPTION.getMsg());
} catch (Exception e) {
result.setSuccess(false);
result.setErrorCode(ErrorMsgEnum.SYSTEM_ERROR.getCode());
result.setErrorMsg(ErrorMsgEnum.SYSTEM_ERROR.getMsg());
log.info("文件上傳失敗 Exception:{}", Throwables.getStackTraceAsString(e));
}
return result;
}
}
2.業(yè)務(wù)層
@Service
@Slf4j
public class FtpFileService {
@Autowired
private FtpFileManager ftpFileManager;
/**
* 上傳文件
*
* @param file
* @return
*/
public FtpUploadResDTO uploadFile(MultipartFile file) {
try {
//判斷上傳文件是否為空
if (null == file || file.isEmpty() || file.getSize() == 0) {
log.info("傳入的文件為空,file:{}", file);
throw new ServiceException(ErrorMsgEnum.EMPTY_FILE);
}
//文件上傳至ftp服務(wù)目錄
FtpFileRecordDO ftpFileRecordDO = ftpFileManager.fileUploadToFtp(file);
if (null == ftpFileRecordDO) {
log.info("文件上傳至ftp服務(wù)目錄異常");
throw new ServiceException(ErrorMsgEnum.FILE_UPLOAD_TO_FTP_EXCEPTION);
}
return ftpFileManager.addFileRecord(ftpFileRecordDO);
} catch (Exception e) {
log.error("業(yè)務(wù)異常,case", e);
throw new ServiceException(ErrorMsgEnum.SYSTEM_ERROR);
}
}
}
3.服務(wù)寫好后,需要把遠(yuǎn)程接口暴露出去
@FeignClient(value = "upload-service", configuration = UpDownFtpFacade.MultipartSupportConfig.class)
public interface UpDownFtpFacade {
/**
* FTP上傳文件
*
* @param file 文件
* @param logId 日志id
* @return
*/
@PostMapping(value = "/ftp/uploadFile",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
FtpApiResponse<FtpUploadResDTO> uploadFileFTP(@RequestPart(value = "file") MultipartFile file,
@RequestParam("logId") String logId);
/**
* 引用配置類MultipartSupportConfig.并且實(shí)例化
*/
@Configuration
class MultipartSupportConfig {
@Bean
public Encoder feignFormEncoder() {
return new SpringFormEncoder();
}
}
}
二.文件上傳客戶端upload-client
@Slf4j
@Component
public class FileManager {
@Autowired
private UpDownFtpFacade upDownFtpFacade;
/**
* 調(diào)用遠(yuǎn)程上傳文件接口
*
* @param file 待上傳的文件
* @return 下載路徑
**/
public FtpApiResponse<FtpUploadResDTO> requestFtpFacade(MultipartFile file) {
try {
DiskFileItem fileItem = (DiskFileItem) new DiskFileItemFactory().createItem("file",
MediaType.ALL_VALUE, true, file.getOriginalFilename());
InputStream input = file.getInputStream();
OutputStream os = fileItem.getOutputStream();
IOUtils.copy(input, os);
MultipartFile multi = new CommonsMultipartFile(fileItem);
FtpApiResponse<FtpUploadResDTO> response = upDownFtpFacade.uploadFileFTP(multi, LogUtil.getLogId());
if (null == response || !response.getSuccess() || null == response.getData()) {
throw new ManagerException(ErrorMsgEnum.FIlE_UPLOAD_FAILED);
}
return response;
} catch (Exception e) {
throw new ManagerException(ErrorMsgEnum.FIlE_UPLOAD_FAILED);
}
}
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Feign遠(yuǎn)程調(diào)用傳遞對(duì)象參數(shù)并返回自定義分頁數(shù)據(jù)的過程解析
- feign遠(yuǎn)程調(diào)用無法傳遞對(duì)象屬性405的問題
- Feign遠(yuǎn)程調(diào)用參數(shù)里面內(nèi)容丟失的解決方案
- Feign遠(yuǎn)程調(diào)用Multipartfile參數(shù)處理
- 使用Feign遠(yuǎn)程調(diào)用時(shí),序列化對(duì)象失敗的解決
- 解決在微服務(wù)環(huán)境下遠(yuǎn)程調(diào)用feign和異步線程存在請(qǐng)求數(shù)據(jù)丟失問題
相關(guān)文章
Java實(shí)現(xiàn)大數(shù)運(yùn)算的實(shí)例代碼
這篇文章主要介紹了Java實(shí)現(xiàn)大數(shù)運(yùn)算的實(shí)例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-06-06
java線程之用Thread類創(chuàng)建線程的方法
本篇文章介紹了,Thread類創(chuàng)建線程的方法。需要的朋友參考下2013-05-05
淺談Springboot實(shí)現(xiàn)攔截器的兩種方式
本文詳細(xì)的介紹了Springboot攔截器的兩種方式實(shí)現(xiàn),一種就是用攔截器,一種就是過濾器,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08
Android?Studio中創(chuàng)建java工程的完整步驟
Android?Studio創(chuàng)建java工程是非常麻煩的,因?yàn)锳ndroid?Studio沒有提供直接創(chuàng)建java工程的方法,下面這篇文章主要給大家介紹了關(guān)于Android?Studio中創(chuàng)建java工程的完整步驟,需要的朋友可以參考下2024-01-01
Java實(shí)現(xiàn)多項(xiàng)式乘法代碼實(shí)例
今天小編就為大家分享一篇關(guān)于Java實(shí)現(xiàn)多項(xiàng)式乘法代碼實(shí)例,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-10-10
基于Spring Boot保護(hù)Web應(yīng)用程序
這篇文章主要介紹了基于Spring Boot保護(hù)Web應(yīng)用程序,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03

