前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式-拦截过滤器模式

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

作者头像
逍遥壮士
发布2020-09-18 11:32:33
1.1K0
发布2020-09-18 11:32:33
举报
文章被收录于专栏:技术趋势技术趋势

背景

每次登陆手机版的各大商城,点击购买的时候都会进行拦截有没有登陆过,若存在的鉴权在有效期或者已经登陆过了,就直接进入支付环节,若登陆信息不存在或失效则直接被要求重新登陆,其中这里面如果用户是没有登陆会被过滤器过滤,是否可能继续请求。

拦截过滤器模式是什么?

拦截过滤器模式(Intercepting Filter Pattern)用于对应用程序的请求或响应做一些预处理/后处理。定义过滤器,并在把请求传给实际目标应用程序之前应用在请求上。过滤器可以做认证/授权/记录日志,或者跟踪请求,然后把请求传给相应的处理程序。

角色:

过滤器(Filter):过滤器在请求处理程序执行请求之前或之后,执行某些任务。

过滤器链(Filter Chain):过滤器链带有多个过滤器,并在 Target 上按照定义的顺序执行这些过滤器。

处理程序(Target ):请求处理程序;

过滤管理器(Filter Manager):过滤管理器管理过滤器和过滤器链。

客户端(Client):Client 是向 Target 对象发送请求的对象。

优点:

低耦合高内聚:通过过滤管理器统一内聚了过滤链,将所有的过滤器统一聚合在一起,而之间耦合度非常低;

复用性高:由于有过滤链,所以可以建立很多的不同链而链中的过滤器是一样的,可以提高过滤器复用性;

预处理:由于用户请求可以在未进入主程序就被拦截到,所有可以提前就预处理了该用户请求的信息;

缺点:

增加程序的复杂度,由于增加了非常多的过滤器会导致该程序复杂度变高;

拦截过滤器模式可以干嘛?

过滤器主要是用来过滤一些非法请求,设置一些请求的编码或格式,将请求中的rquest信息进行过滤或添加一些请求头信息,常用的是配置统一编码或者配置cors一些非法攻击等。

个人理解:

拦截过滤器就像你去坐地铁,首先要通过检查,符合才能进,不符合可能直接被拉走,然后进入地铁,要刷卡、扫码或投币,如果刚好手机没电了那不好意思用投币或刷卡吧,当进入后,会根据你乘的信息出站时统一收费。

拦截过滤器模式类图

源码下载:https://gitee.com/hong99/design-model/issues/I1IMES

实现代码

代码语言:javascript
复制
/**
 * @Auther: csh
 * @Date: 2020/7/3 15:13
 * @Description:抽象过滤器(abstract filter)
 */
public interface IFilter {
    public void execute(String request);
}
代码语言:javascript
复制
/**
 * @Auther: csh
 * @Date: 2020/7/3 15:20
 * @Description: 权限过滤器(filter)
 */
public class AuthorizationFilter implements IFilter {
    @Override
    public void execute(String request) {
        if(request.contains("admin")){
            System.out.println("进入管理后台");
        }else{
            System.out.println("没有权限");
        }
    }
}
代码语言:javascript
复制
/**
 * @Auther: csh
 * @Date: 2020/7/3 15:21
 * @Description:日志记录过滤器(filter)
 */
public class LogFitler implements IFilter {
    @Override
    public void execute(String request) {
        System.out.println("日志记录:"+request);
    }
}
代码语言:javascript
复制
/**
 * @Auther: csh
 * @Date: 2020/7/3 15:30
 * @Description:请求进行处理
 */
public class Target {
    public void execute(String request){
        String user = request.contains("admin")?"管理员":"用户";
        System.out.println(user+"进行登陆");
    }
}
代码语言:javascript
复制
/**
 * @Auther: csh
 * @Date: 2020/7/3 15:31
 * @Description:过滤链
 */
public class FilterChain {
    private List<IFilter> filters = new ArrayList <IFilter>();
    private Target target;

    public void addFilter(IFilter filter){
        filters.add(filter);
    }

    public void excute(String request){
        for (IFilter filter : filters) {
            filter.execute(request);
        }
        target.execute(request);
    }

    public void setTarget(Target target){
        this.target = target;
    }
}
代码语言:javascript
复制
/**
 * @Auther: csh
 * @Date: 2020/7/3 15:37
 * @Description:过滤管理器
 */
public class FilterManager {
    FilterChain filterChain;

    public FilterManager(Target target){
        filterChain = new FilterChain();
        filterChain.setTarget(target);
    }

    public void setFilter(IFilter filter) {
        filterChain.addFilter(filter);
    }

    public void filterRequest(String request){
        filterChain.excute(request);
    }
}
代码语言:javascript
复制
/**
 * @Auther: csh
 * @Date: 2020/7/3 15:40
 * @Description:用户
 */
public class Client {
    FilterManager filterManager;

    public void setFilterManager(FilterManager filterManager){
        this.filterManager = filterManager;
    }

    public void sendRequest(String request){
        filterManager.filterRequest(request);
    }

}
代码语言:javascript
复制
/**
 * @Auther: csh
 * @Date: 2020/7/3 15:41
 * @Description:
 */
public class Test {
    public static void main(String[] args) {
        FilterManager filterManager = new FilterManager(new Target());
        filterManager.setFilter(new AuthorizationFilter());
        filterManager.setFilter(new LogFitler());

        Client client = new Client();
        client.setFilterManager(filterManager);
        client.sendRequest("admin");
        client.sendRequest("USER");
    }
}

结果

代码语言:javascript
复制
进入管理后台
日志记录:admin
管理员进行登陆
没有权限
日志记录:USER
用户进行登陆

源码下载:https://gitee.com/hong99/design-model/issues/I1IMES

最后

拦截过滤器,其实过滤器是过滤器,拦截器是拦截器,在实际spring、springboot或其他框架中,过滤器主要用来过滤一些非法的用户请求或用户请求的时候在请求头中添加特定的定信息,而拦截器则通过过滤器传递过来的信息对用户进行拦截,然后再转发到相应的下一层。

过滤器场景使用:

在web.xml中

代码语言:javascript
复制
<filter>
   <filter-name>CORS</filter-name>
   <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
   <init-param>
      <param-name>cors.allowOrigin</param-name>
      <param-value>*</param-value>
   </init-param>
   <init-param>
      <param-name>cors.supportedMethods</param-name>
      <param-value>GET, POST, HEAD, PUT, DELETE</param-value>
   </init-param>
   <init-param>
      <param-name>cors.supportedHeaders</param-name>
      <param-value>Access-Control-Allow-Origin,Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
   </init-param>
   <init-param>
      <param-name>cors.exposedHeaders</param-name>
      <param-value>Set-Cookie</param-value>
   </init-param>
   <init-param>
      <param-name>cors.supportsCredentials</param-name>
      <param-value>true</param-value>
   </init-param>
</filter>

参考文章:

https://www.cnblogs.com/syuf/p/6845406.html

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-07-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 技术趋势 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 源码下载:https://gitee.com/hong99/design-model/issues/I1IMES
  • 源码下载:https://gitee.com/hong99/design-model/issues/I1IMES
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档