过滤器模式

    

  过滤器模式,顾名思义,就是过滤对象用的,对需要过滤的对象,进行一些验证,或者加某些特定信息,或者删减信息都可以。如果你想定义多个过滤规则,那么就需要定义多个过滤器,一般每个过滤器只实现一种规则。然后多个过滤器会连在一起,形成一个过滤器链,想想我们的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切面的实现方式就用到了过滤器模式,后面有机会我会介绍的。

  未完待续。。。

原文地址:https://www.cnblogs.com/xiexin2015/p/9037865.html