OpenFeign组件
什么是 OpenFeign ?
OpenFeign 是一个声明式的 HTTP 客户端,它使得我们可以非常方便地调用 HTTP 接口。OpenFeign 是 Netflix 开源的 Feign 项目的扩展,旨在与 Spring Cloud 紧密集成。它通过注解来定义接口,类似于 Spring MVC 的控制器,使得开发者可以专注于业务逻辑,而不需要关注 HTTP 请求的具体实现。
OpenFeign 使用
- 添加OpenFeign依赖
1 | |
TIP : OpenFeign 通常和 loadbalancer 接口负载均衡组件搭配使用。
- 声明 FeignClient 客户端接口
1 | |
注:
@FeignClient是用来标记这个接口是一个 Feign 客户端的注解。name = ApiConstants.SERVICE_NAME指定了这个 Feign 客户端所调用的服务名称。这个名称通常是在注册中心(如 Eureka 或 Nacos)中注册的服务名称。
String PREFIX = "/file": 定义了一个前缀常量,用于接口中 URI 的路径前缀。@PostMapping注解标记这个方法将执行一个 HTTP POST 请求。value = PREFIX + "/test"指定了这个 POST 请求的路径,这里是"/file/test"。
2.1 创建 ApiConstants 常量类,定义一个服务名称常量,即本身注册到 Nacos 中的服务名称。
1 | |
到这里,对象存储服务就将 /file/test 接口的 Feign 客户端,封装到 api 模块中了,有其他服务想要调用对象存储服务的 /file/test 接口,只需引入 xiaohashu-oss-api 模块即可。
- 启用Feign客户端
编辑XiaohashuUserBizApplication启动类,添加@EnableFeignClients注解,以启用引入的xiaohashu-oss-api模块中定义好的Feign客户端。
1 | |
- 服务间调用
以上工作完成后,就可以在用户服务中,注入FileFeignApi客户端,来调用对象存储服务的/file/test接口了。
OpenFeign 支持表单请求
针对于图片上传,普通的调用方式还不行,需要额外配置表单提交。
添加依赖:
1 | |
feign-form 依赖是干嘛的?
feign-form 是一个 Feign 扩展库,专门用于处理表单数据的编码。它提供了一些增强功能,使 Feign 客户端能够更方便地处理表单提交和文件上传等操作。
表单配置类
新建一个 FeignFormConfig表单配置类。
1 | |
SpringFormEncoder是 Feign 提供的一个编码器,用于处理表单提交。它将对象编码为表单数据格式(如application/x-www-form-urlencoded或multipart/form-data),以便在 HTTP 请求中使用。
封装 Feign 调用
创建一个 /rpc 包,统一放置服务间调用代码,并新建 OssRpcService 类。
1 | |
将调用对象存储服务上传文件的逻辑,单独封装一层 service,并声明一个 uploadFile() 方法。方法中,若调用对象存储服务成功,则返回图片链接;否则,返回 null 。
Feign 请求拦截器:实现 userId 服务间透传
如果说,我们想在下游服务中获取当前请求对应的用户 ID , 比如,修改用户信息接口,会调用对象存储微服务,在对象存储微服务中,通过前面封装的上下文组件获取当前用户 ID,能拿的到吗?
为什么获取不到?
原因是网关路由转发到服务时,网关层会设置用户 ID 到请求头中,但是,服务之间调用是通过 Feign 来完成的,是没有经过网关的,下游服务再去从请求头中获取用户 ID,自然是拿不到。
如何解决上面这个问题呢?
可以为 Feign 单独配置一个请求拦截器,在调用其他服务时,将当前用户 ID 添加到请求头中,保证下游服务也能够通过上下文组件拿到用户 ID。
- 配置 Feign 请求拦截器
将这个功能,一并放到上下文组件中。首先,编辑xiaoha-spring-boot-starter-biz-context上下文组件的pom.xml, 添加feign核心依赖:
1 | |
在上下文组件中,创建一个 /interceptor 包,用于放置拦截器,并新建 FeignRequestInterceptor 请求拦截器
1 | |
自定义
Feign请求拦截器需继承自RequestInterceptor接口;在
apply()方法中,先通过LoginUserContextHolder.getUserId(); 拿到当前请求对应的用户 ID;判断若不为空,则将用户 ID 添加到请求头中,以便下游服务再次获取;
- 自动化配置
在 /config 包下,新建一个 FeignContextAutoConfiguration 自动化配置类。
1 | |
- 将刚刚自定义的
FeignRequestInterceptor请求拦截器,自动注入到 Spring 容器中。
同时,别忘了在 org.springframework.autoconfigure.AutoConfiguration.imports 文件中,添加上 FeignContextAutoConfiguration 的完整包路径。