基于【 责任链模式】二 || 网关zuul过滤器封装
一、基于责任链模式封装网关拦截
上一篇文章中已经使用建造者模式对网关拦截进行封装,存在一个问题,在连接器build中,每一个拦截都要进行true判断,代码看起来冗余,下面使用责任链模式封装
1、基于责任链设计模式封装: 创建网关请求拦截接口
/**
* @Description: 基于责任链设计模式封装: 网关请求拦截
* @Author: kevin
* @CreateTime: 2019-08-26 22:09
* @Version: V1.0
*/
public interface GatewayHandler {
/**
* Handler处理器: 网关拦截处理请求
*/
public void service(RequestContext ctx, String ipAddress, HttpServletRequest request, HttpServletResponse response); /**
* 指向下一个handler
*/
public void setNextHandler(GatewayHandler nextGatewayHandler); /**
* 获取下一个Handler
*
* @return
*/
public GatewayHandler getNextHandler();
}
2、实现接口业务逻辑
/**
* @Description: 相同的Handler业务逻辑重构
* @Author: kevin
* @CreateTime: 2019-08-26 23:02
* @Version: V1.0
*/
public class BaseHandler { protected GatewayHandler nextGatewayHandler; public void setNextHandler(GatewayHandler nextGatewayHandler) {
this.nextGatewayHandler=nextGatewayHandler;
} /**
* 网关拦截
* @param ctx
* @param code
* @param errorMsg
*/
protected void resultError(RequestContext ctx, String errorMsg) {
ctx.setResponseStatusCode(401);
// 网关响应为false 不会转发服务
ctx.setSendZuulResponse(false);
ctx.setResponseBody(errorMsg); }
}
/**
* @Description: [流程1] 基于责任链设计模式封装: 黑名单拦截
* @Author: kevin
* @CreateTime: 2019-08-26 22:17
* @Version: V1.0
*/
@Slf4j
//@Component
public class BlackBlockHandler extends BaseHandler implements GatewayHandler { @Override
public void service(RequestContext ctx, String ipAddress, HttpServletRequest request, HttpServletResponse response) {
// 4.从数据库动态读取,判断是黑名单,设置网关响应为false
if("127.0.0.1".equals(ipAddress)){
resultError(ctx, "ip:" + ipAddress + ",Insufficient access rights");
// 直接停止了,不继续走后面的Handler
return;
}
log.info(">>>>>>ip:{},验证通过>>>>>>>", ipAddress);
// 执行下一个流程Handler
nextGatewayHandler.service(ctx,ipAddress,request,response);
} @Override
public GatewayHandler getNextHandler() {
return null;
} }
/**
* @Description: [流程2] 基于责任链设计模式封装: 参数验签拦截
* @Author: kevin
* @CreateTime: 2019-08-26 22:18
* @Version: V1.0
*/
@Slf4j
//@Component
public class ParamsValidateHandler extends BaseHandler implements GatewayHandler {
@Override
public void service(RequestContext ctx, String ipAddress, HttpServletRequest request, HttpServletResponse response) {
// 5.外网传递参数签名拦截
Map<String, String> verifyMap = SignUtil.toVerifyMap(request.getParameterMap(), false);
if(!SignUtil.verify(verifyMap)){
resultError(ctx, "ip:" + ipAddress + ",Sign fail");
return;
}
// 执行下一个流程Handler
nextGatewayHandler.service(ctx,ipAddress,request,response);
} @Override
public void setNextHandler(GatewayHandler gatewayHandler) { } @Override
public GatewayHandler getNextHandler() {
return null;
}
}
/**
* @Description: [流程3] 基于责任链设计模式封装: API权限控制
* @Author: kevin
* @CreateTime: 2019-08-26 22:19
* @Version: V1.0
*/
@Slf4j
//@Component
public class ApiAuthorizeHandler extends BaseHandler implements GatewayHandler {
@Override
public void service(RequestContext ctx, String ipAddress, HttpServletRequest request, HttpServletResponse response) {
String servletPath = request.getServletPath();
log.info(">>>>>servletPath:" + servletPath + ",servletPath.substring(0, 5):" + servletPath.substring(0, 5));
// 内部服务调用不需要accessToken验证,如果public开头,表示授权公司访问接口
if (!servletPath.substring(0, 7).equals("/public")) {
// 执行下一个流程Handler
nextGatewayHandler.service(ctx,ipAddress,request,response);
return;
}
String accessToken = request.getParameter("accessToken");
log.info(">>>>>accessToken验证:" + accessToken);
if (StringUtils.isEmpty(accessToken)) {
resultError(ctx, "AccessToken cannot be empty");
return;
}
// 调用接口验证accessToken是否失效
BaseResponse<JSONObject> appInfo = verificaCodeServiceFeign.getAppInfo(accessToken);
log.info(">>>>>>data:" + appInfo.toString());
if (!isSuccess(appInfo)) {
resultError(ctx, appInfo.getMsg());
return;
}
// 执行下一个流程Handler
nextGatewayHandler.service(ctx,ipAddress,request,response);
} @Override
public GatewayHandler getNextHandler() {
return null;
}
}
3、基于责任链设计模式封装: 使用工厂获取Handler
/**
* @Description: 基于责任链设计模式封装: 使用工厂获取Handler
* @Author: kevin
* @CreateTime: 2019-08-26 22:27
* @Version: V1.0
*/
public class FactoryHandler { /**
* 责任链启动方式:
*
* 1.将每一个Handler存放到集合中实现遍历
* 可以把handler放入数据库,设置开关,不用每次修改代码
*
* @return
*/
public static GatewayHandler getOneHandler() {
// 1.黑名单判断
GatewayHandler gatewayHandler1 = (GatewayHandler) SpringContextUtil.getBean("blackBlockHandler");
// 2.api验证签名
GatewayHandler gatewayHandler2 = (GatewayHandler) SpringContextUtil.getBean("paramsValidateHandler");
gatewayHandler1.setNextHandler(gatewayHandler2);
// 3.api接口验证token
GatewayHandler gatewayHandler3 = (GatewayHandler) SpringContextUtil.getBean("apiAuthorizeHandler");
gatewayHandler2.setNextHandler(gatewayHandler3);
return gatewayHandler1; }
}
4、基于责任链设计模式封装: 责任链调用方
/**
* @Description: 基于责任链设计模式封装: 责任链调用方
* @Author: kevin
* @CreateTime: 2019-08-26 22:35
* @Version: V1.0
*/
//@Component
public class ResponsibilityClient {
/**
* 责任链调用
*/
public void responsibility(RequestContext ctx, String ipAddress, HttpServletRequest request,
HttpServletResponse response) {
GatewayHandler oneHandler = FactoryHandler.getOneHandler();
oneHandler.service(ctx, ipAddress, request, response);
}
}
5、网关过滤器中调用
@Override
public Object run() throws ZuulException { RequestContext ctx = RequestContext.getCurrentContext();
// 1.获取请求对象
HttpServletRequest request = ctx.getRequest();
// 2.获取响应对象
HttpServletResponse response = ctx.getResponse(); // 3.获取客户端真实ip地址
String ipAddr = IpUtil.getIpAddr(request);
if (StringUtils.isEmpty(ipAddr)) {
resultError(ctx, "未能够获取到ip地址");
} // 4 设计模式二: 基于责任链模式封装
responsibilityClient.responsibility(ctx,ipAddr,request,response); return null; }
基于【 责任链模式】二 || 网关zuul过滤器封装的更多相关文章
- 基于【 建造者模式】一 || 网关zuul过滤器封装
一.springcloud的zuul网关拦截 1.黑名单拦截 2.参数验签 3.Api接口权限验证 二.网关拦截实现方式 1.继承ZuulFilter方法,实现业务逻辑 @Component @Slf ...
- 设计模式学习笔记(十四)责任链模式实现以及在Filter中的应用
责任链模式(Chain Of Responsibility Design Pattern),也叫做职责链,是将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求.当有请求发生时,可将请求沿着这条 ...
- GOF23设计模式之责任链模式(chain of responsibility)
一.责任链模式概述 将能够处理同一类请求的对象连成一条链,所提交的请求沿着链传递,链上的对象逐个判断是否有能力处理该请求. 如果能则处理,否则传递给链上的下一个对象去处理. 定义责任链 (1)通过链表 ...
- 网络编程Netty入门:责任链模式介绍
目录 责任链模式 责任链模式的简单实现 Netty中的ChannelPipeline责任链 服务端接收客户端连接 pipeline初始化 入站事件和出站事件 Pipeline中的Handler Pip ...
- Java 设计模式系列(二二)责任链模式
Java 设计模式系列(二二)责任链模式 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求 ...
- 由浅入深讲解责任链模式,理解Tomcat的Filter过滤器
本文将从简单的场景引入, 逐步优化, 最后给出具体的责任链设计模式实现. 场景引入 首先我们考虑这样一个场景: 论坛上用户要发帖子, 但是用户的想法是丰富多变的, 他们可能正常地发帖, 可能会在网页中 ...
- 二十四种设计模式:责任链模式(Chain of Responsibility Pattern)
责任链模式(Chain of Responsibility Pattern) 介绍为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求.将这些对象连成一条链,并沿着这条链传递该请求,直 ...
- 设计模式之二十:责任链模式(Chain of Responsibility)
感觉这个设计模式和组合模式一样是一种非常巧妙的设计模式,在须要使用它的地方假设不使用这样的设计模式代码会变的非常复杂,可是这样的设计模式的基本原理又是非常easy的. 责任链模式: 通过使多个对象都有 ...
- C#设计模式:责任链模式
设计模式是面向对象编程的基础,是用于指导程序设计.在实际项目开发过程中,并不是一味将设计模式进行套用,也不是功能设计时大量引入设计模式.应该根据具体需求和要求应用适合的设计模式.设计模式是一个老话题了 ...
随机推荐
- [转]arcgis for server 10.2 下载及安装
转自:https://blog.csdn.net/nominior/article/details/80211963 https://blog.csdn.net/mrib/article/detail ...
- django 实战3 simpleui
pip3 install django-import-export pip3 install django-simpleui pip3 install mysqlclient python3 mana ...
- Python3基础 输出逐行递增的小星星
Python : 3.7.3 OS : Ubuntu 18.04.2 LTS IDE : pycharm-community-2019.1.3 ...
- dart里面的时间处理:
原文地址:https://www.cnblogs.com/wyhlightstar/p/11059942.html 1.获取当前时间 var now = new DateTime.now(); pri ...
- Linux记录-批量安装ssh(转载)
首先,需要检查expect是否安装:rpm -qa|grep expect 然后,在操作机上创建公钥:ssh-keygen 一路回车即可 创建好之后到/root/.ssh/下就可以看到id开头的2个文 ...
- 如何发布自己的APP到Google Play上
如何发布自己的APP到Google Play上 参考链接: https://justforuse.github.io/blog/zh-cn/2019/08/publish-your-own-app-t ...
- 斐波那契数列&&上台阶
使用装饰器的场景 当我们想对多个函数增加一个相同的功能时,例如计数统计,缓存计算结果,记录日志等 # coding:utf-8 # [题目1] # 斐波那契数列 又称黄金分割数列,指的是这样的一个数列 ...
- clickHouse可视化查询工具
clickHouse以卓越的查询性能著称,目前在大数据的存储和分析领域有广泛应用,目前TreeSoft已支持clickHouse的数据在线查询分析,可以与Mysql,oracle等数据库并存操作. 1 ...
- Python机器学习基础教程-第2章-监督学习之决策树集成
前言 本系列教程基本就是摘抄<Python机器学习基础教程>中的例子内容. 为了便于跟踪和学习,本系列教程在Github上提供了jupyter notebook 版本: Github仓库: ...
- Django中cookie和session的操作
一.cookie和session cookie:在网站中,http请求是无状态的.也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户.cookie的出现就是 ...