實踐案例包括兩個專案,服務提供者專案名:upload-service,呼叫服務專案名:upload-client,主要給出兩個服務之間的呼叫過程,檔案上傳功能不提供
專案框架: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>
一.檔案上傳服務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("檔案上傳結束 resDTO:{},耗時:{}", 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.業務層
@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服務目錄
FtpFileRecordDO ftpFileRecordDO = ftpFileManager.fileUploadToFtp(file);
if (null == ftpFileRecordDO) {
log.info("檔案上傳至ftp服務目錄異常");
throw new ServiceException(ErrorMsgEnum.FILE_UPLOAD_TO_FTP_EXCEPTION);
}
return ftpFileManager.addFileRecord(ftpFileRecordDO);
} catch (Exception e) {
log.error("業務異常,case", e);
throw new ServiceException(ErrorMsgEnum.SYSTEM_ERROR);
}
}
}
3.服務寫好後,需要把遠端介面暴露出去
@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.並且例項化
*/
@Configuration
class MultipartSupportConfig {
@Bean
public Encoder feignFormEncoder() {
return new SpringFormEncoder();
}
}
}
二.檔案上傳客戶端upload-client
@Slf4j
@Component
public class FileManager {
@Autowired
private UpDownFtpFacade upDownFtpFacade;
/**
* 呼叫遠端上傳檔案介面
*
* @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);
}
}
}