基于【 责任链模式】二 || 网关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#设计模式:责任链模式
设计模式是面向对象编程的基础,是用于指导程序设计.在实际项目开发过程中,并不是一味将设计模式进行套用,也不是功能设计时大量引入设计模式.应该根据具体需求和要求应用适合的设计模式.设计模式是一个老话题了 ...
随机推荐
- System.Net.WebRequest.cs
ylbtech-System.Net.WebRequest.cs 发出对统一资源标识符(URI)的请求.这是一个 abstract 类. 1.返回顶部 1. #region 程序集 System, V ...
- vue---lodash的使用
Lodash就是这样的一套工具库,它内部封装了诸多对字符串.数组.对象等常见数据类型的处理函数,其中部分是目前ECMAScript尚未制订的规范,但同时被业界所认可的辅助函数.莫倩每天使用npm安装L ...
- openresty开发系列23--lua面向对象
openresty开发系列23--lua面向对象 面向对象编程(Object Oriented Programming,OOP)是一种非常流行的计算机编程架构.java,c++,.net等都支持面向对 ...
- Source Insight 4.0配置格式化工具AStyle.exe
Source Insight 4.0配置格式化工具AStyle.exe 摘自:https://blog.csdn.net/u012156133/article/details/81566871 1. ...
- 【物联网】传感器+wifi传输+回复+显示
https://www.jianshu.com/p/cb0274d612b5 https://timgsa.baidu.com/timg?image&quality=80&size=b ...
- 01点睛Spring MVC 4.1-搭建环境
转发:https://www.iteye.com/blog/wiselyman-2213906 1.1 简单示例 通篇使用java config @Controller声明bean是一个控制器 @Re ...
- Sublime Text3安装及常用插件安装
为了使用强大好用的代码编辑器来进行selenium3+Python3的自动化测试. 使用Sublime Text 3非常适合. 1.下载安装 首先到http://www.sublimetext.com ...
- certutil在传输payload中的新奇技巧
好久没更新博客了,最近在实习的过程中还是见识到不少东西. 不多说,直接开始正文. 首先说一下certutil在渗透测试中用到的特别多,下载文件,计算hash,以及base64编码等等. 在这里介绍ba ...
- LeetCode 145. 二叉树的后序遍历(Binary Tree Postorder Traversal)
145. 二叉树的后序遍历 145. Binary Tree Postorder Traversal 题目描述 给定一个二叉树,返回它的 后序 遍历. LeetCode145. Binary Tree ...
- ZooKeeper 相关问题
[为什么部署个数是奇数个?] zookeeper有这样一个特性:集群中只要有过半的机器是正常工作的,那么整个集群对外就是可用的.即 2n 个机器的集群,最多可以容忍 n-1 个机器不可用,这个容忍度与 ...