之前我们完成了gateway传递token到微服务中,但是这还不够,因为有时候我们微服务是一个调用链路,每个微服务的请求可以来自于网关也可以来自于其他微服务,我们只完成了gateway传递token,还没有完成微服务之间使用openfeign发送请求时的token传递。
1、我们在common项目里加一个类,把之前我们创建的那个openfeign-demo项目(时间过去有点久了,翻看一下前文)中的DefaultFeignConfig文件复制到common的config包下。openfeign框架给我们预留了一个拦截器RequestInterceptor,所以我们把openfeign的依赖复制到common的pom文件里并添加拦截器。
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>
package com.mj.common.config;import cn.hutool.core.util.StrUtil;
import com.mj.common.tool.UserTool;
import feign.Logger;
import feign.Request;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.context.annotation.Bean;import java.util.concurrent.TimeUnit;public class DefaultFeignConfig {@Beanpublic Logger.Level feignLogLevel() {return Logger.Level.FULL;}@Beanpublic Request.Options options() {//第一个参数是连接超时时间,第二个参数是处理超时时间return new Request.Options(2000, TimeUnit.MILLISECONDS, 2000, TimeUnit.MILLISECONDS, true);}@Beanpublic RequestInterceptor userRequestInterceptor() {return new RequestInterceptor() {@Overridepublic void apply(RequestTemplate requestTemplate) {String userid = UserTool.getUserId();if (StrUtil.isNotBlank(userid)) {requestTemplate.header("userid", userid);}}};}
}
2、这样就可以清理掉openfeign中的重复文件了,由于我们在学习过程中修改了不少东西,所以之前的openfeign-demo也要再修改一下。修改主启动类,把common里的config类扫描进去。
package com.mj.openfeign;import com.mj.common.config.DefaultFeignConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;@EnableFeignClients(defaultConfiguration = DefaultFeignConfig.class)
@SpringBootApplication(scanBasePackages = "com.mj")
public class OpenFeignDemoApplication {public static void main(String[] args) {SpringApplication.run(OpenFeignDemoApplication.class, args);}
}
3、修改NacosClientDemoClient文件,添加调用talk接口,并且要把更新的接口地址修改好。
package com.mj.openfeign.client;import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;@FeignClient("nacos-client-demo")
public interface NacosClientDemoClient {@GetMapping("/nacos-client-demo/api/call")String testCall();@GetMapping("/nacos-client-demo/api/talk")String testTalk();
}
4、修改NacosClientController,添加一个调用talk的测试接口。
package com.mj.openfeign.client;import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;@FeignClient("nacos-client-demo")
public interface NacosClientDemoClient {@GetMapping("/nacos-client-demo/api/call")String testCall();@GetMapping("/nacos-client-demo/api/talk")String testTalk();
}
5、网关里要添加对openfeign-demo的路由配置。
spring:main:# gateway组件中的spring-boot-starter-webflux和springboot作为web项目启动必不可少的spring-boot-starter-web出现冲突web-application-type: reactiveapplication:name: gateway-democloud:nacos:server-addr: 192.168.3.54:80username: nacospassword: nacosdiscovery:group: devopsnamespace: sitconfig:namespace: sitgroup: devopsgateway:routes:- id: nacos-client-demo #指定服务名uri: lb://nacos-client-demo #去注册中心找这个服务名predicates: #断言,匹配访问的路径- Path=/nacos-client-demo/api/** #服务访问路径filters: # 过滤器- AddRequestHeader=headername, I am a header! # 添加请求头- My=zhangsan,lisi,wangwu- id: open-feign-demouri: lb://open-feign-demopredicates:- Path=/open-feign-demo/api/**config:import: nacos:${spring.application.name}?refresh=true
server:port: 8888
6、重启服务,通过curl命令带有token进行调用openfeign-demo,再由openfeign-demo调用nacos-client-demo中的talk接口。
curl -H "token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyTmFtZSI6InpoYW5nc2FuIiwidXNlcklkIjoiMTIzIiwiZXhwIjoxN zQwNzU1NDE2fQ.Xqpgk_lqhpxIIvxSo70mb3LQuozREIOituLyZKKYYaA" http://127.0.0.1:8888/open-feign-demo/api/talkhi,123
可见返回结果页正确解析到了userId,这样我们就基本完成了token在微服务体系中的传递功能,当然在日常工作中还会有其他的做法,万变不离其宗,大家就按照咱们练习的样子去改造就可以了。