欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

过滤器模式

程序员文章站 2022-04-28 09:47:37
过滤器模式,顾名思义,就是过滤对象用的,对需要过滤的对象,进行一些验证,或者加某些特定信息,或者删减信息都可以。如果你想定义多个过滤规则,那么就需要定义多个过滤器,一般每个过滤器只实现一种规则。然后多个过滤器会连在一起,形成一个过滤器链,想想我们的servlet的过滤器,其实就是这样的,下面我就根据 ......

    

  过滤器模式,顾名思义,就是过滤对象用的,对需要过滤的对象,进行一些验证,或者加某些特定信息,或者删减信息都可以。如果你想定义多个过滤规则,那么就需要定义多个过滤器,一般每个过滤器只实现一种规则。然后多个过滤器会连在一起,形成一个过滤器链,想想我们的servlet的过滤器,其实就是这样的,下面我就根据servlet过滤器实现方式,来模拟一下过滤器的模式:

  1、首先定义两个需要过滤的对象,

  Request:

package com.hd.filter;

public class Request {

    private String requestStr;

    public Request(String requestStr) {
        this.requestStr = requestStr;
    }

    public String getRequestStr() {
        return requestStr;
    }

    public void setRequestStr(String requestStr) {
        this.requestStr = requestStr;
    }

    public void addStr(String str){
        this.requestStr += str;
    }
}

  Response:

package com.hd.filter;

public class Response {

    private String ResponseStr;

    public Response(String responseStr) {
        ResponseStr = responseStr;
    }

    public String getResponseStr() {
        return ResponseStr;
    }

    public void setResponseStr(String responseStr) {
        ResponseStr = responseStr;
    }

    public void addStr(String str){
        this.ResponseStr += str;
    }
}

 

  2、然后需要定义一个filter接口:

package com.hd.filter;

public interface Filter {

    void doFilter(Request request, Response response, FilterChain filterChain);
}

  

  3、接着我们再定义一个过滤器链FilterChain,用来将多个过滤器有序的链起来:

package com.hd.filter;

import java.util.ArrayList;
import java.util.List;

public class FilterChain {

    private List<Filter> filterChains = new ArrayList<Filter>();

    public static FilterChain build(){
        return new FilterChain();
    }

    public FilterChain addFilter(Filter filter){
        this.filterChains.add(filter);
        return this;
    }

    public FilterChain removeFilter(Filter filter){
        this.filterChains.remove(filter);
        return this;
    }

}

 

  4、下面就是定义具体的filter实现了:

package com.hd.filter;

public class HTMLFilter implements Filter {

    @Override
    public void doFilter(Request request, Response response, FilterChain filterChain) {

        System.out.println("HTMLFilter Request");
        request.addStr("-HTML-");
        filterChain.doFilter(request, response);    //这里是第一个重点的地方,只有这样设计,request才可以按照正序执行过滤,response按照倒序执行过滤
        response.addStr("-HTML-");
        System.out.println("HTMLFilter Response");
    }
}

 

package com.hd.filter;

public class SensitiveFilter implements Filter {

    @Override
    public void doFilter(Request request, Response response, FilterChain filterChain) {

        System.out.println("SensitiveFilter Request");
        request.addStr("-Sensitive-");
        filterChain.doFilter(request, response);
        response.addStr("-Sensitive-");
        System.out.println("SensitiveFilter Response");
    }
}

 

package com.hd.filter;

public class LowerUpcaseFilter implements Filter {

    @Override
    public void doFilter(Request request, Response response, FilterChain filterChain) {

        System.out.println("LowerUpcaseFilter Request");
        request.addStr("-LowerUpcase-");
        filterChain.doFilter(request, response);
        response.addStr("-LowerUpcase-");
        System.out.println("LowerUpcaseFilter Response");
    }
}

 

  5、下面我们还差一个重要的点,就是如何把所有的过滤器串起来,还按照顺序往下执行。如果你有经过思考后的话,不难想到应该是在FilterChain的 doFilter 方法里做文章:

    private int index =0;

    public void doFilter(Request request, Response response){

        if(index < filterChains.size()){
            filterChains.get(index++).doFilter(request, response, this);
        }else{
            return;
        }

    }

  定义一个变量,用来标记当前需要处理的是哪个过滤器,这是第二个重点

  6、最后写下测试代码:

package com.hd.filter;

public class TestFilter {

    public static void main(String[] args){

        FilterChain filterChain = FilterChain.build();
        filterChain.addFilter(new HTMLFilter());
        filterChain.addFilter(new SensitiveFilter());
        filterChain.addFilter(new LowerUpcaseFilter());

        Request request = new Request("request");
        Response response = new Response("response");
        filterChain.doFilter(request, response);

        System.out.println(request.getRequestStr());
        System.out.println(response.getResponseStr());
    }
}

 

  运行结果如下:

HTMLFilter Request
SensitiveFilter Request
LowerUpcaseFilter Request
LowerUpcaseFilter Response
SensitiveFilter Response
HTMLFilter Response
request-HTML--Sensitive--LowerUpcase-
response-LowerUpcase--Sensitive--HTML-

 

  如果你写过递归算法的话,应该会和我有同感,感觉过滤器有点像递归算法,一层层的往下套,然后执行到最后一层的之后,再一个个原路返回。

  过滤器在spring中也有重点运用,AOP切面的实现方式就用到了过滤器模式,后面有机会我会介绍的。

  未完待续。。。