Spring Cloud下使用Feign Form实现微服务之间的文件上传

​ Spring Cloud现在已经被越来越多的公司采用了,微服务架构比传统意义上的单服务架构从复杂度上多了很多,出现了很多复杂的场景。比如,我们的产品是个app,支持第三方登录功能,在手机端调用第三方授权接口之后,返回了用户的相关信息,比如open_id,性别,头像等。这些信息我们需要保存在我们服务器上,当时针对头像是应该保存图片的url还是图片本身发生了歧义,在一番讨论之后,得出的结果是,我们需要通过url将图片下载到我们本地,然后调用我们自己的文件微服务中上传功能保存起来。

​ 跨服务之间调用,我们采用的是Feign组件,原生的Feign组件并不支持文件上传,但是如果添加了Feign-Form模块,那么就能上传文件,下面我通过一篇文章来讲述如何通过Feign上传文件,代码已经上传github地址。

说明

个人博客首发: https://Shiyajian.github.io

github项目地址:https://github.com/Shiyajian/examples ,请找spring-cloud/chapter1

本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

工具

IDE :IntelliJ IDEA

JDK : jdk 8

构建工具:Gradle 4.10.2

Spring Cloud 版本:Finchley.SR2 (截止2018-11-25最新的GA版本,基于boot 2.0.6)

Spring Boot 版本:2.0.6.RELEASE (截止2018-11-25最新为2.1.0.RELEASE)

此处采用Gradle而没有使用Maven作为依赖构建和管理的工具,主要原因是我们公司目前使用的是Gradle,而且从编译速度,代码可读性和清晰度上都远远优于Maven。

项目结构

​ 本项目分为三个角色,分别如下:

eurka-server : 注册中心

provider-server: 服务提供者,此处模拟一个文件服务器,提供文件上传功能

consumer-server: 服务消费者,此处模拟一个业务服务,需要调用文件上传服务

大致的依赖图如下:

Spring Cloud下使用Feign Form实现微服务之间的文件上传

配置并运行

​ 我们首先通过运行感受一下通过Feign上传文件的流程,在整个项目可以完整运行后,我们再参考文章和代码一起分析其中设置,并将其应用到自己的应用中

首先clone项目到本地

git clone https://github.com/Shiyajian/examples.git

安装并配置Gradle

将项目导入到IDEA中

确认IDEA支持Lombok插件,默认IDEA都支持的,此步骤可忽略

更改IDEA设置,Project Settings(Mac中为Preferences)-> Compiler -> Annoatation Processors -> [√] Enable annotation processing

刷新Gradle,下载依赖并编译

启动注册中心

找到 examples/spring-cloud/eureka-server中的EurekaApplication,运行main方法

打开浏览器,运行::8761/,能打开证明成功

启动Provider项目

找到 examples/spring-cloud/chapter1/provider/provider-service中的ProviderApplication,运行main方法

刷新注册中心页面,找到服务证明成功

运行Consumer项目中的测试

打开examples/spring-cloud/chapter1/consumer/consumer-server/src/test目录

修改com.shiyajian.examples.consumer.service.impl.ConsumerServiceImplTest类中文件的路径为本机电脑上存在的文件

运行测试方法

方法绿灯结束,在控制台能找到输出为成功

Provider 服务配置说明

Provider服务为上传服务的提供者,这里模拟的是一个文件服务器,通过上面图,我们可以看到项目分为2部分,下面就进行详细解读:

provider-api

这个项目最终打成一个可以被引用的jar包,consumer-server通过引用这个jar包可以通过注入方式引用其中的方法,provider-server也需要引用这个jar包,然后实现其中的逻辑,供consumer-server远程调用。配置api的方法如下:

添加org.springframework.cloud:spring-cloud-starter-openfeign依赖,只需要这一个依赖就够了,里面保存Fegin-Form等依赖。

编写配置类FeignMultipartSupportConfig.java

public class FeignMultipartSupportConfig { @Bean @Primary @Scope("prototype") public Encoder multipartFormEncoder(ObjectFactory<HttpMessageConverters> messageConverters) { return new FeignSpringFormEncoder(new SpringEncoder(messageConverters)); } }

编写自定义的Encoder,因为这个有个设计得BUG,本身可以解析文件数组,但是代码缺少对应的判断,此处参考文章:https://blog.csdn.net/tony_lu229/article/details/73823757,代码不贴了,详细见工程

定义自己的接口,这里我定义的是ProviderClient,代码简单如下:

@FeignClient(value = "provider-server", configuration = FeignMultipartSupportConfig.class) public interface ProviderClient { @PostMapping(value = "client/upload/{id}", consumes = MULTIPART_FORM_DATA_VALUE) String uploadFile(@RequestPart("file") MultipartFile file, @PathVariable("id") String id, @RequestParam("name") String name); @PostMapping(value = "client/uploads", consumes = MULTIPART_FORM_DATA_VALUE) List<ProviderResponse> uploadFiles(@RequestPart("files") MultipartFile[] files, @RequestParam("author") String author); }

这个接口定义时候需要有以下注意的几点:

@FeignClient中的value,对应的是服务实现类在eureka中注册的名字,也就是spring.application.name的值

configuration必须配置,就是咱们上面添加的两个类,用来编解码使用

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzxdxg.html