spring cloud feign实现远程调用服务传输文件的方法

实践案例包括两个项目,服务提供者项目名: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>

创建FeignClient接口(用于指定远程调用的服务)

// 申明这是一个Feign客户端,并且指明服务id
@FeignClient(value = "com-spring-caclulate")
public interface CacluFeignClient {

 // 这里定义了类似于SpringMVC用法的方法,就可以进行RESTful的调用了
 @RequestMapping(value = "/caclu/{num}", method = RequestMethod.GET)
 public Item caclulate(@PathVariable("num") Integer num);

}

一.文件上传服务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);
  }
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Spring Cloud Feign的文件上传实现的示例代码

    在Spring Cloud封装的Feign中并不直接支持传文件,但可以通过引入Feign的扩展包来实现,本来就来具体说说如何实现. 服务提供方(接收文件) 服务提供方的实现比较简单,就按Spring MVC的正常实现方式即可,比如: @RestController public class UploadController { @PostMapping(value = "/uploadFile", consumes = MediaType.MULTIPART_FORM_DATA_VAL

  • vue使用el-upload上传文件及Feign服务间传递文件的方法

    一.前端代码 <el-upload class="step_content" drag action="string" ref="upload" :multiple="false" :http-request="createAppVersion" :data="appVersion" :auto-upload="false" :limit="1&quo

  • 使用Spring Cloud Feign上传文件的示例

    最近经常有人问Spring Cloud Feign如何上传文件.有团队的新成员,也有其他公司的兄弟.本文简单做个总结-- 早期的Spring Cloud中,Feign本身是没有上传文件的能力的(1年之前),要想实现这一点,需要自己去编写Encoder 去实现上传.现在我们幸福了很多.因为Feign官方提供了子项目feign-form ,其中实现了上传所需的 Encoder . 注:笔者测试的版本是Edgware.RELEASE.Camden.Dalston同样适应本文所述. 加依赖 <depen

  • 使用Feign扩展包实现微服务间文件上传

    在Spring Cloud 的Feign组件中并不支持文件的传输,会出现这样的错误提示: feign.codec.EncodeException: class [Lorg.springframework.web.multipart.MultipartFile; is not a type supported by this encoder. at feign.codec.Encoder$Default.encode(Encoder.java:90) ~[feign-core-9.5.1.jar:

  • 使用Feign实现微服务间文件传输

    在很多时候我们会遇到微服务之间文件传输,很多时候我们可以通过序列化等方式解决(如图片等). 最近项目中有个excel上传,以及多媒体文件上传,直接报错. 也试了2种解决方式,都不可行. 1.写一个文件Encoder解析器,会出现其他的rest请求出现encoder错误 2.springcloud feign有一个规范,不可以传输2个对象,可以是一个对象带几个参数方式. 那么我们现在需要一种方式,不配置全局的解析器,而是通过Feign Builder 去管理上传文件,这种方式管理起来也较为方便.

  • Spring Cloud Feign文件传输的示例代码

    一.配置文件解析器 服务提供者和消费者都需要配置文件解析器,这里使用 commons-fileupload 替换原有的解析器: 依赖: <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency> 注入 be

  • SpringCloud使用Feign文件上传、下载

    文件上传.下载也是实际项目中会遇到的场景,本篇我们介绍下springcloud中如何使用feign进行文件上传与下载. 还是使用feign 进行http的调用. 一.Feign文件上传 服务提供方java代码: /** * 文件上传 * @param file 文件 * @param fileType * @return */ @RequestMapping(method = RequestMethod.POST, value = "/uploadFile", produces = {

  • spring cloud feign实现远程调用服务传输文件的方法

    实践案例包括两个项目,服务提供者项目名:upload-service,调用服务项目名:upload-client,主要给出两个服务之间的调用过程,文件上传功能不提供 项目框架:spring-boot 2.0.1.RELEASE.spring-cloud Finchley.RELEASE 依赖: <dependency> <groupId>io.github.openfeign.form</groupId> <artifactId>feign-form<

  • SpringCloud Feign如何在远程调用中传输文件

    1. 文件远程传输主要涉及3点: 请求方式, 媒体类型, 序列化与反序列化, 把握住了这3点,基本上就可以搞 2. 使用Feign传输,首先搭建起Feign的架子 2.1 引入spring-cloud-starter-eureka-server依赖,用于启动一个eureka注册中心 2.2 引入spring-cloud-starter-eureka依赖,用于开启向eureka注册中心注册自己 2.3 在调用远程服务的客户端引入spring-cloud-starter-feign, 用于使用fei

  • spring cloud Feign使用@RequestLine遇到的坑

    Feign使用@RequestLine遇到的坑 如何在微服务项目中调用其它项目的接口试使用spring cloud feign声明式调用. /** * 客户端请去 * @author RAY * */ @FeignClient(name="store",configuration=FooConfiguration .class) public interface UserFeignClient { @RequestLine("GET /simple/{id}") p

  • 使用Spring Cloud Feign作为HTTP客户端调用远程HTTP服务的方法(推荐)

    在Spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端.我们可以使用JDK原生的URLConnection.Apache的Http Client.Netty的异步HTTP Client, Spring的RestTemplate.但是,用起来最方便.最优雅的还是要属Feign了. Feign简介 Feign是一种声明式.模板化的HTTP客户端.在Spring Cloud中使用Feign, 我们可以做到使用HTT

  • 使用Spring Cloud Feign远程调用的方法示例

    在Spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端.我们可以使用JDK原生的URLConnection.Apache的Http Client.Netty的异步HTTP Client, Spring的RestTemplate.但是,用起来最方便.最优雅的还是要属Feign了. Feign简介 Feign是一个声明式的Web服务客户端,使用Feign可使得Web服务客户端的写入更加方便. 它具有可插拔注释支持

  • Spring cloud Feign 深度学习与应用详解

    简介 Spring Cloud Feign是一个声明式的Web Service客户端,它的目的就是让Web Service调用更加简单.Feign提供了HTTP请求的模板,通过编写简单的接口和插入注解,就可以定义好HTTP请求的参数.格式.地址等信息.Feign会完全代理HTTP请求,开发时只需要像调用方法一样调用它就可以完成服务请求及相关处理.开源地址:https://github.com/OpenFeign/feign.Feign整合了Ribbon负载和Hystrix熔断,可以不再需要显式地

  • spring cloud feign不支持@RequestBody+ RequestMethod.GET报错的解决方法

    1.问题梳理: 异常:org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported 很明显是最终feign执行http请求时把这个方法认定为POST,但feign client中又定义了RequestMethod.GET 或 @GetMapping,冲突导致报错 那么为什么feign会认为这个方法是post呢? 源码追踪: 1.我们从feignClient注解

  • Spring Cloud Feign实例讲解学习

    前面博文搭建了一个Eureka+Ribbon+Hystrix的框架,虽然可以基本满足服务之间的调用,但是代码看起来实在丑陋,每次客户端都要写一个restTemplate,为了让调用更美观,可读性更强,现在我们开始学习使用Feign. Feign包含了Ribbon和Hystrix,这个在实战中才慢慢体会到它的意义,所谓的包含并不是Feign的jar包包含有Ribbon和Hystrix的jar包这种物理上的包含,而是Feign的功能包含了其他两者的功能这种逻辑上的包含.简言之:Feign能干Ribb

  • Spring Cloud Feign简单使用详解

    概述 在Spring Cloud EureKa Ribbon 服务注册-发现-调用一文中简单的介绍了在Spring Cloud中如何使用EureKa和Ribbon.文章中使用了RestTemplate去访问其他的restful微服务接口.其实在Spring Cloud还可以使用Feign来访问其他的restful微服务接口.使用起来更加的简洁明了. 集成Feign 修改一下Spring Cloud EureKa Ribbon 服务注册-发现-调用中order service的pom配置,把Feg

  • 详解Spring Cloud Feign 熔断配置的一些小坑

    1.在使用feign做服务调用时,使用继承的方式调用服务,加入Hystrix的熔断处理fallback配置时,会报错,已解决. 2.使用feign默认配置,熔断不生效,已解决. 最近在做微服务的学习,发现在使用feign做服务调用时,使用继承的方式调用服务,加入Hystrix的熔断处理fallback配置时,会报错,代码如下: @RequestMapping("/demo/api") public interface HelloApi { @GetMapping("user/

随机推荐