过滤器模式
Posted 海小鑫
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了过滤器模式相关的知识,希望对你有一定的参考价值。
过滤器模式,顾名思义,就是过滤对象用的,对需要过滤的对象,进行一些验证,或者加某些特定信息,或者删减信息都可以。如果你想定义多个过滤规则,那么就需要定义多个过滤器,一般每个过滤器只实现一种规则。然后多个过滤器会连在一起,形成一个过滤器链,想想我们的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切面的实现方式就用到了过滤器模式,后面有机会我会介绍的。
未完待续。。。
以上是关于过滤器模式的主要内容,如果未能解决你的问题,请参考以下文章