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)用過(guò)程,文件上傳功能不提供
項(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 { // 這里定義了類(lèi)似于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("文件上傳開(kāi)始!}"); 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ù)寫(xiě)好后,需要把遠(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); /** * 引用配置類(lèi)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ù)并返回自定義分頁(yè)數(shù)據(jù)的過(guò)程解析
- feign遠(yuǎn)程調(diào)用無(wú)法傳遞對(duì)象屬性405的問(wèn)題
- 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ù)丟失問(wèn)題
相關(guān)文章
IDEA配置靜態(tài)資源熱加載操作(Springboot修改靜態(tài)資源不重啟)
這篇文章主要介紹了IDEA配置靜態(tài)資源熱加載操作(Springboot修改靜態(tài)資源不重啟),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-10-10在Mybatis中association標(biāo)簽多層嵌套的問(wèn)題
這篇文章主要介紹了在Mybatis中association標(biāo)簽多層嵌套的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03springboot-assembly自定義打包全過(guò)程
這篇文章主要介紹了springboot-assembly自定義打包全過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06java8如何根據(jù)list對(duì)象中的屬性過(guò)濾篩選
這篇文章主要介紹了java8如何根據(jù)list對(duì)象中的屬性過(guò)濾篩選,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05深入理解Java注解類(lèi)型(@Annotation)
這篇文章主要介紹了深入理解Java注解類(lèi)型(@Annotation),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-05-05