基于【 责任链模式】二 || 网关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#设计模式:责任链模式
设计模式是面向对象编程的基础,是用于指导程序设计.在实际项目开发过程中,并不是一味将设计模式进行套用,也不是功能设计时大量引入设计模式.应该根据具体需求和要求应用适合的设计模式.设计模式是一个老话题了 ...
随机推荐
- no match for call to ‘(std::__cxx11::string {aka std::__cxx11::basic_string
问题: t->package().ship_id(sqlRow[1]);其中 ship_id为 结构体package中的string类型.如下: typedef struct Package{ ...
- Hashset(不能添加相同的字符进入数组)
参考: https://ke.qq.com/webcourse/index.html#cid=434021&term_id=100518216&taid=377652179413386 ...
- 基于Java API for WebSocket (JSR-356)的标准websocket客户端
maven依赖 springboot <dependency> <groupId>org.springframework.boot</groupId> <ar ...
- Java Sound : generate play sine wave - source code
转载自:http://ganeshtiwaridotcomdotnp.blogspot.com/2011/12/java-sound-generate-play-sine-wave.html Work ...
- Jrebel激活方法(转)
本次服务长期稳定提供给各位同学使用哦!服务器地址:https://jrebel.qekang.com/{GUID}在线GUID地址:在线生成GUID如果失效刷新GUID替换就可以!打开jrebel 激 ...
- 【JS新手教程】JS获取当前星期几的几种方法
该文通过获取星期几的几种方法,介绍JS里的数组,判断,和字符串截取,可以当作新手教程看,小白也看的懂.获取星期几,可通过Date()对象的getDay()获取,获取的是一个数字,对应的是0,1,2,3 ...
- echars 3.0 去掉柱状图阴影用什么属性
原图展示: 效果图展示: 在代码中注释掉这段 // tooltip : { // trigger: 'axis', // axisPointer : { // 坐标轴指示器,坐标轴触发有效 // ty ...
- EC11编码器的使用方法
1. EC11编码器的原理图如下 2. 旋转的时候,波形如下,EC11转1格,产生一个上升沿的中断,思路就是检测AX4-1的上升沿中断(平时是低电平),进入中断服务函数,检测AX4-2的电平,低电平逆 ...
- 【ARTS】01_44_左耳听风-201900909~201900915
ARTS: Algrothm: leetcode算法题目 Review: 阅读并且点评一篇英文技术文章 Tip/Techni: 学习一个技术技巧 Share: 分享一篇有观点和思考的技术文章 Algo ...
- confluence6.14.1linux安装破解
一.简介 Confluence为团队提供一个协作环境.在这里,团队成员齐心协力,各擅其能,协同地编写文档和管理项目.从此打破不同团队.不同部门以及个人之间信息孤岛的僵局,Confluence真正实现了 ...