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