最近在交接项目的过程中看到了拦截过滤器模式,用于在核心请求的"前后处理",比如在请求前对参数进行校验、做请求统计、数据埋点;在请求后记录返回结果、打印日志、处理日志(写入ES,HBase等),有点类似于aop的环绕around通知。
核心组件:
Filter(过滤器):在处理请求之前或者之后执行相应动作。
Filter Chain(Filter Chain):一组过滤器的组合,按照添加的顺序依次执行。
Target:目标处理对象
Filter Manager:过滤管理器管理
核心需求:
1.主流程:现在主要对用户行为进行校验;
2.在主流程之前要对用户的信息进行验证;之后记录日志和结果。
首先建立AuditFilter接口类:
public interface AuditFilter {
public void execute(AuditContext auditContext);
}
并实用户信息校验,记录日志,记录结果等三个过滤器类:
AuditCheckFilter:
public class AuditCheckFilter implements AuditFilter {
public void execute(AuditContext auditContext) {
System.out.println("AuditCheckFilter...");
if ("wahaha".equals(auditContext.getName())) {
System.out.println("user check right");
} else {
System.out.println("user check wrong");
}
}
}
AuditLogFilter:
public class AuditLogFilter implements AuditFilter {
public void execute(AuditContext auditContext) {
System.out.println("AuditLogFilter...");
auditContext.setLog("log");
}
}
AuditResultFilter:
public class AuditResultFilter implements AuditFilter {
public void execute(AuditContext auditContext) {
System.out.println("AuditResultFilter...");
auditContext.setResult("result");
}
}
创建Target接口:
public interface Target {
public void execute(AuditContext auditContext);
}
创建Target实现类:
public class AuditTarget implements Target {
public void execute(AuditContext auditContext) {
System.out.println("do audit target");
}
}
创建过滤器链AuditFilterChain:
public class AuditFilterChain {
private List<AuditFilter> filters = new ArrayList<AuditFilter>();
public void addFilter(AuditFilter filter) {
filters.add(filter);
}
public void execute(AuditContext auditContext) {
for(AuditFilter filter: filters) {
filter.execute(auditContext);
}
}
}
创建过滤器管理器AuditFilterManager:
public class AuditFilterManager {
private UserCheckFilter userCheckFilter;
private AuditResultFilter auditResultFilter;
private AuditLogFilter auditLogFilter;
private AuditTarget auditTarget;
private AuditFilterChain preAuditFilterChain;
private AuditFilterChain postAuditFilterChain;
public AuditFilterManager() {
preAuditFilterChain = new AuditFilterChain();
postAuditFilterChain = new AuditFilterChain();
userCheckFilter = new UserCheckFilter();
auditResultFilter = new AuditResultFilter();
auditLogFilter = new AuditLogFilter();
preAuditFilterChain.addFilter(userCheckFilter);
postAuditFilterChain.addFilter(auditResultFilter);
postAuditFilterChain.addFilter(auditLogFilter);
auditTarget = new AuditTarget();
}
public void execute(AuditContext context) {
preAuditFilterChain.execute(context);
auditTarget.execute(context);
postAuditFilterChain.execute(context);
}
}
Demo演示:
public class InterceptingFilterDemo {
public static void main(String[] args) {
AuditFilterManager auditFilterManager = new AuditFilterManager();
AuditContext auditContext = new AuditContext();
auditContext.setCity("shanghai");
auditContext.setName("wahaha");
System.out.println(auditContext);
auditFilterManager.execute(auditContext);
System.out.println(auditContext);
}
}
运行结果:
AuditContext{name='wahaha', city='shanghai', result='null', log='null'}
AuditCheckFilter...
user check right
do audit target
AuditResultFilter...
AuditLogFilter...
AuditContext{name='wahaha', city='shanghai', result='result', log='log'}
为什么要用这个模式?
将主流程抽象出来,加上前后处理流程,逻辑清晰易懂。
Author:忆之独秀
Email:leaguenew@qq.com
注明出处:https://blog.csdn.net/lavorange/article/details/106304431