本文模拟一个FilterChain过滤器处理请求Request,并且返回Response。
用到的设计模式是,
责任链。
责任链设计模式
每个对象都持有下家对象的引用而形成一条链,请求在这个链条上传递,直到某个对象处理这个请求。发出请求的客户端并不知道该条链子的哪一个对象处理了消息。
代码实现
Request和Response类
public class Request {
public String req;
public Request(String req) {
this.req = req;
}
}
Filter接口
public interface Filter {
void doFilter(Request request, Response response, Filter filterChain);
}
public class Response {
public String resp = "response";
}
HTMLFilter和SensitiveFilter类
public class HTMLFilter implements Filter {
@Override
public void doFilter(Request request, Response response, Filter filterChain) {
request.req = request.req.replace("<", "[");
request.req = request.req.replace(">", "]") + "----HTMLFilter";
filterChain.doFilter(request, response, filterChain);
response.resp += "-----HTMLFilter";
}
}
public class SensitiveFilter implements Filter {
@Override
public void doFilter(Request request, Response response, Filter filterChain) {
request.req = request.req.replace("敏感", "*") + "----SensitiveFilter";
filterChain.doFilter(request, response, filterChain);
response.resp += "----SensitiveFilter";
}
}
FilterChain类
public class FilterChain implements Filter {
private List<Filter> chain = new ArrayList<Filter>();
public void addFilter(Filter filter) {
chain.add(filter);
}
private int index = 0;
@Override
public void doFilter(Request request, Response response, Filter filterChian) {
if (index == chain.size()) return;
Filter filter = chain.get(index++);
filter.doFilter(request, response, filterChian);
}
}
测试类Main
public class Main {
public static void main(String[] args) {
FilterChain filterChain = new FilterChain();
filterChain.addFilter(new HTMLFilter());
filterChain.addFilter(new SensitiveFilter());
Request request = new Request("<敏感词汇>");
Response response = new Response();
filterChain.doFilter(request, response, filterChain);
System.out.println(request.req);
System.out.println(response.resp);
}
}
执行结果:
[*词汇]—-HTMLFilter—-SensitiveFilter
response—-SensitiveFilter—–HTMLFilter
小结
- 本文实现的是双向的责任链,web容器对请求的处理也是类似。主要采用迭代的方式对request和response处理,即
filterChain.doFilter(request, response, filterChain),和
filter.doFilter(request, response, filterChian)
这几处代码。 - 也有单向的责任链,实现起来相对简单。
- 责任链的两种划分,
- 内置责任链,链中的各个环节都有对下家的引用,其实是个栈。
- 外置责任链,单独维护一个链条,每个环节都不知道自己的下家。
- 责任链和装饰者的比较,
- 装饰者更像是内置链条的责任链。但就我所使用的情况看,责任链通常是有预定义的链条的;而装饰者更多的是根据实际情况自定义装饰、处理顺序的。
- 装饰者的每一层装饰,都是从不同维度来完成一项工作。比如著名的java中的inputstream,什么文件输入流,有缓存的输入流,字节型输入流等,就是从不同的维度来处理输入流的。
- 责任链也可以采用抽象类实现,大概思路,
- 抽象出一个类,包含处理请求的方法和返回下一个下家的引用。
- 具体工作类重写处理请求的方法。