设计模式:拦截过滤器模式

拦截器模式,顾名思义,对请求进行拦截,既可以请求执行前拦截,也可以在请求处理之后拦截。在请求到达实际请求目标之前,进行拦截,对请求进行预处理,比如认证、鉴权、记录日志。拦截也可以后置处理,可以记录日志信息,计算请求调用时间等。

拦截器模式的实践

springMVC请求拦截过程就是一个经典的拦截器模式实践,通过对http请求在拦截器链中进行匹配,筛选出匹配成功的拦截器列表,遍历列表,进行请求拦截操作,进行预处理或后置处理。

那如何设计一个简单的拦截器实践?

参考SpringMVC源码,设计一个简单的拦截器实践。

  1. 定义拦截器
  2. 拦截器管理
  3. 发起请求

1.定义拦截器,首先定义一个拦截器接口,接口是行为的规范,即拥有什么功能

/**
 * @author yujiaxing
 * @date 2021/09/27
 */
public interface Interceptor{
    // 前置拦截
    void before(InvocationChain invocationChain);
    // 拦截
    void intercept(InvocationChain invocationChain, String param);
    // 后置拦截
    void after(InvocationChain invocationChain);

}

#定义多个拦截器,这里定义两个拦截器 LogInterceptor,SensitiveInfoConversionInterceptor


# LogInterceptor定义
/**
 * @author yujiaxing
 * @date 2021/09/27
 */
@Component
public class LogInterceptor implements Interceptor {

    @Resource
    private BusinessService businessService;

    @Override
    public void before(InvocationChain invocationChain) {
        System.out.println("LogInterceptor before ...");
    }

    @Override
    public String intercept(InvocationChain invocationChain, String param) {
        this.before(invocationChain);
        businessService.logRecord(param);
        invocationChain.invoke(param);
        this.after(invocationChain);
        return null;
    }

    @Override
    public void after(InvocationChain invocationChain) {
        System.out.println("LogInterceptor after ...");
    }
}


# SensitiveInfoConversionInterceptor 定义


/**
 * @author yujiaxing
 * @date 2021/09/27
 */
@Component
public class SensitiveInfoConversionInterceptor implements Interceptor {

    @Resource
    private BusinessService businessService;

    @Override
    public void before(InvocationChain invocationChain) {
        System.out.println("SensitiveInfoConversionInterceptor before ...");
    }

    @Override
    public void intercept(InvocationChain invocationChain, String param) {
        this.before(invocationChain);
        businessService.sensitiveInfoConversion(param);
        invocationChain.invoke(param);
        this.after(invocationChain);
    }

    @Override
    public void after(InvocationChain invocationChain) {
        System.out.println("SensitiveInfoConversionInterceptor after ...");
    }
}

# 其中业务类的定义
/**
 * @author yujiaxing
 * @date 2021/09/27
 */
@Service
public class BusinessService {

    public void perform(String param) {
        System.out.println("【正常请求----业务代码】,当前参数:"+param);
    }
    
    public void logRecord(String param) {
        System.out.println("【日志拦截业务代码】,当前参数:"+param);
    }

    public void sensitiveInfoConversion(String param) {
        System.out.println("【敏感信息转换业务代码】转换前参数:"+param+" , 转换后参数:"+param.replace("大大大","**"));
    }
}

2.定义拦截器链

/**
 * @author yujiaxing
 * @date 2021/09/27
 */
@Data
public class InvocationChain {

    private int index = 0;
    private List<Interceptor> interceptorList;
    private BusinessService businessService = new BusinessService();

    public void invoke(String request) {

        if (index != interceptorList.size()) {
            Interceptor interceptor = interceptorList.get(index);
            index++;
            interceptor.intercept(this, request);
        }else{
            businessService.perform(request);
        }
    }
}

3.测试,发起请求

@SpringBootTest
class InvocationChainTest {

    @Autowired
    BusinessService businessService;
    @Autowired
    private LogInterceptor logInterceptor;
    @Autowired
    private SensitiveInfoConversionInterceptor sensitiveInfoConversionInterceptor;

    @Test
    public void testInterceptor() {
        // 定义过滤器链,添加过滤器
        InvocationChain invocationChain = new InvocationChain();
        ArrayList<Interceptor> interceptors = new ArrayList<>();
        interceptors.add(logInterceptor);
        interceptors.add(sensitiveInfoConversionInterceptor);

        invocationChain.setInterceptorList(interceptors);

        // 发起请求
        String param = "金箍棒,大大大大";
        invocationChain.invoke(param);
    }

}

结果如下:
在这里插入图片描述

拦截器是函数递归调用,处理流程和栈一样,先进后出。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值