Fegin拦截器解决各微服务之间数据下沉

上篇说了当前端访问微服务网关,借助ZuulFilter过滤器来过滤所有请求,获取request,判断cookie是否有身份短令牌,request的header中是否有Jwt令牌,redis中是否有Jwt令牌。但是这个数据传递只能是前端访问微服务时,网关进行过滤,在微服务访问微服务时,则没有数据向下传递。

所以我们使用Fegin拦截器来做微服务之间的数据下沉,数据传递。

因为在每个微服务使用Fegin远程调用时都会使用,所以写在了common包下。


import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;/** Fegin远程调用拦截器*/
public class FeignClientInterceptor implements RequestInterceptor {/*** 每次远程调用都会走这个方法* @param requestTemplate*/@Overridepublic void apply(RequestTemplate requestTemplate) {//的到requst中Header数据ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();if(requestAttributes!=null){HttpServletRequest request = requestAttributes.getRequest();//取出header中的Jwt令牌Enumeration<String> headerNames = request.getHeaderNames();if(headerNames!=null){while(headerNames.hasMoreElements()){String headerName = headerNames.nextElement();String headerValue = request.getHeader(headerName);//向下传递requestTemplate.header(headerName,headerValue);}}}}}

可以从代码中看到,implements RequestInterceptor每个微服务远程调用都会走下面的实现方法,在apply()方法中,我们获取当前的request中Header中所有数据,然后用requestTemplate.header(headerName,headerValue) 将所有数据下沉。

 

所以在使用fegin远程调用时是可以这样利用fegin拦截器进行数据下沉的,但是在使用别的方法远程调用微服务时这个拦截器是不会处理的。

比如说,当我们使用的是restTemplate进行远程调用时,

 //注入restTemplate@Bean@LoadBalanced//开启客户端负载均衡public RestTemplate restTemplate(){return new RestTemplate(new OkHttp3ClientHttpRequestFactory());}
 //rest远程获取数据ResponseEntity<Map> forEntity = restTemplate.getForEntity(dataUrl, Map.class);

此时进行数据下沉需要进行数据处理,借助request中header的HttpEntity进行数据存储,数据传递。

比如

private AuthToken applyToken(String clientId, String clientSecret, String username, String password) {//获取认证服务 的微服务实例ServiceInstance serviceInstance = loadBalancerClient.choose(XcServiceList.XC_SERVICE_UCENTER_AUTH);if (serviceInstance == null) {LOGGER.error("choose an auth instance fail");ExceptionCast.cast(AuthCode.AUTH_LOGIN_AUTHSERVER_NOTFOUND);}//  http://IP:port/URI uri = serviceInstance.getUri();String authUrl = uri + "/auth/oauth/token";//HttpEntity//bodyLinkedMultiValueMap<String, String> body = new LinkedMultiValueMap<>();body.add("grant_type","password");body.add("username",username);body.add("password",password);//headersLinkedMultiValueMap<String, String> header = new LinkedMultiValueMap<>();header.add("Authorization",getHttpBasic(clientId,clientSecret));HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(body, header);//设置restTemplate远程调用时,对400,401错误不报错,正确返回数据restTemplate.setErrorHandler(new DefaultResponseErrorHandler(){@Overridepublic void handleError(ClientHttpResponse response) throws IOException {if(response.getRawStatusCode()!=400&&response.getRawStatusCode()!=401){super.handleError(response);}}});//申请令牌的信息Map map = null;try {ResponseEntity<Map> bodyMap = restTemplate.exchange(authUrl, HttpMethod.POST, httpEntity, Map.class);map = bodyMap.getBody();} catch (RestClientException e) {e.printStackTrace();LOGGER.error("request oauth_token_password error: {}",e.getMessage());e.printStackTrace();ExceptionCast.cast(AuthCode.AUTH_LOGIN_APPLYTOKEN_FAIL);}if(map == null ||map.get("access_token") == null ||map.get("refresh_token") == null ||map.get("jti") == null){//确定用户名 或者 密码错误异常抛出if(map!=null){String error_description = (String) map.get("error_description");if(error_description.indexOf("UserDetailsService returned null")>=0){ExceptionCast.cast(AuthCode.AUTH_ACCOUNT_NOTEXISTS);}else if(error_description.indexOf("坏的凭证")>=0){ExceptionCast.cast(AuthCode.AUTH_CREDENTIAL_ERROR);}}//jti是jwt令牌的唯一标识作为用户身份令牌ExceptionCast.cast(AuthCode.AUTH_LOGIN_APPLYTOKEN_FAIL);}AuthToken authToken = new AuthToken();//访问令牌(jwt)String jwt_token = (String) map.get("access_token");//刷新令牌(jwt)String refresh_token = (String) map.get("refresh_token");//jti,作为用户的身份标识String access_token = (String) map.get("jti");authToken.setJwt_token(jwt_token);authToken.setAccess_token(access_token);authToken.setRefresh_token(refresh_token);return authToken;}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/570970.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

免杀原理与实践

杀软原理 目前杀毒软件的原理主要有3种&#xff1a; 1.引擎与病毒库的交互作用&#xff0c;通过特征码提取与病毒库中的特征码进行比对识别病毒。 2.启发式Heuristic&#xff0c;通过程序的一些行为和特征来判断。 3.在虚拟机技术上的启发式&#xff0c;通过建立一个虚拟环境运…

分布式事务的理解和解决方法

什么是分布式事务&#xff1f; 什么是分布式系统?部署在不同结点上的系统通过网络交互来完成协同工作的系统。 比如&#xff1a;充值加积分的业务&#xff0c;用户在充值系统向自己的账户充钱&#xff0c;在积分系统中自己积分相应的增加。充值系统和积分系统是两个不同的系统…

delphi 搭建安卓开发环境

delphi 搭建安卓开发环境 DELPHI安装成功以后&#xff0c;怀着激动的心情&#xff0c;使用IDE向导生成安卓DEMO程序&#xff0c;BUILD&#xff0c;想马上看到编译成功的提示&#xff0c;结果报错&#xff0c;不由得傻眼了。DELPHI怎么这么差&#xff1f; 原来DELPHI安装成功以后…

关于Centos7启动,ens33无IP问题解决

今天启动虚拟机xshell6一直连不上&#xff0c;之前一直好好的&#xff0c;怎么突然连不上了&#xff0c;很奇怪&#xff0c;上去看看连接方式也没问题。 然后ip addr 一看ens33下无ip&#xff0c;然后就查资料解决&#xff0c;看到很多解决办法试了都没解决。 最后的解决办法…

Xshell6突然连不上K8S所在的虚拟机

哎&#xff0c;最近一直出现部署运维问题&#xff0c;就很头疼&#xff0c;很影响进度。 今天早上xshell6突然就连不上虚拟机了&#xff0c;在虚拟机内部Ping百度也是没问题的。 但是xshell就是不给连&#xff0c;看xm的dhcp也在。 如果是VMnetDhcp服务关闭&#xff0c;重启…

Kubernetes 创建pod一直处于ContainerCreating 状态解决过程

。 遇到问题了又&#xff0c;创建的pods一直出于ContainerCreating状态。 说一下自己这次的解决流程。 首先去网上搜一搜这种类似问题的解决办法&#xff0c;然后结合自己的情况进行解决。 首先遇到的我遇到这个问题和网上一哥们的问题很相似&#xff0c;所以借鉴一下https:…

SpringCloud项目接入华为云Paas平台CES一些注意事项

1.注册华为云账号获取个人中心-》管理我的凭证-》访问密钥-》下载ak&#xff0c;sk密钥。 2.本地项目maven需要配置华为云私服 <profile> <id>nexusProfile</id> <repositories> <repository> <id>cse1</id><url>http://mave…

springcloud不使用数据库微服务启动异常解决

项目在文件处理微服务不使用数据库时&#xff0c;项目启动异常。 解决办法如下&#xff1a;

fastDFS页面浏览器缓存解决

在使用fastDFS做文件系统时&#xff0c;图片浏览器缓存影响删除结果显示。 解决办法如下: 在fastDFS的容器中的nginx配置禁止浏览器缓存:

字符串用法

count()方法 描述 count() 方法用于统计字符串里某个字符出现的次数。可选参数为在字符串搜索的开始与结束位置。 str.count(sub, start 0,endlen(string)) 参数 sub -- 搜索的子字符串start -- 字符串开始搜索的位置。默认为第一个字符,第一个字符索引值为0。end -- 字符串中结…

OpenResty+Lua+redis+mysql实现高性能高可用限流缓存

OpenResty(又称&#xff1a;ngx_openresty) 是一个基于 NGINX 的可伸缩的 Web 平台.并发性能可在10k-1000k OpenResty安装 1.添加仓库执行命令 yum install yum-utils yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo 2.执行安装 yum …

OpenResty(nginx)限流配置实现

一般情况下&#xff0c;首页的并发量是比较大的&#xff0c;即使有了多级缓存&#xff0c;如果有大量恶意的请求&#xff0c;也会对系统造成影响。而限流就是保护措施之一。 nginx提供两种限流的方式&#xff1a; 一是控制速率 二是控制并发连接数 控制速率 控制速率的方式…

数据同步的解决方案Canal

Canal实现数据同步的原理&#xff1a; 1.是根据模拟mysql slave的主从交互协议&#xff0c;伪装自己是mysql slave&#xff0c;向mysql master发送dump请求。 2.mysql master收到dump请求后,开始推送 binary log给canal 3.canal解析binary log对象&#xff08;原始byte流&am…

复习……方法的重载

Lesson Six                         2018-04-20  00:48:57 1.一个项目或工程&#xff0c;一定是由一个一个类构成的。2.类是抽象的&#xff0c;比如建筑图纸。而具体的建筑&#xff0c;是根据图纸建设成的&#xff0c;实际上就是类的实例化3.完成一…

对Kafka的总结

定位&#xff1a;kafka是一款分布式&#xff0c;高吞吐量&#xff0c;基于发布/订阅的消息中间件。 核心组件&#xff1a; broker&#xff1a;kafka服务器&#xff0c;负责消息的存储和转发。 topic&#xff1a;主题&#xff0c;消息的类别&#xff0c;kafka按照topic分类消…

Ribbon中的负载均衡算法实现

Ribbon响应时间权重负载均衡算法&#xff0c;假设有3台服务器A,B&#xff0c;C响应时间为10&#xff0c;40&#xff0c;80ms。 算法公式&#xff1a;weighsofar 总响应时长- 本服务器平均响应时长 A&#xff1a;0130-10120 B:120130-40210 C:210130-80260 将3个轮询数值放…

maven私服配置

环境&#xff1a; eclipse 、maven、nexus。 1、配置setting.xml文件 1.1、配置本地仓库位置&#xff1a;文件中&#xff0c;存在节点 “localRepository”&#xff0c;默认是注释&#xff0c;也就是本地仓库使用默认地址“Default: ~/.m2/repository”&#xff0c;一般为系统…

NAT模式下虚拟机与主机网络关系配置

哎&#xff0c;又是烦人的网络关系耽误了好长时间。 当前情况是使用NAT模式使得主机与虚拟机与外网连通 具体配置如下&#xff1a; 这是VM上配置 如下是虚拟机ip配置 vi /etc/sysconfig/network-scripts/ifcfg-ens33 vi /etc/resolv.conf service network restart

python学习笔记-day6-函数的延续【汉字转拼音模块,函数返回多个值,匿名函数,列表生成式,generator生成器,三元运算符】...

继续来说函数的后续知识点&#xff0c;主要是函数返回多个值&#xff0c;匿名函数&#xff0c;三元运算符&#xff0c;算是比较小的知识点。 一、汉字转拼音模的使用 1、安装模块 #install xpinyin 2、如果使用 结果&#xff1a; 二、函数返回多个值 1、python的函数可以同时返…