Tomcat容器以及一些Web框架都使用了责任链设计模式来对请求和响应进行逐步的处理或者过滤,本文使用Java语言来模拟过滤器的实现。其序列图以下:java

若是简单的使用责任链模式,用一个List来实现层层过滤,则会致使request的处理是按照顺序来执行,response也会按照顺序来执行,这就与咱们指望的response按照倒序来执行相悖。所以要用一种方式实现request顺序处理,response倒序处理。编程
实现
类图大体以下:设计模式

首先,写两个实体类,Request和Responseapp
Request.java框架
[java] view plain copyide
- public class Request {
- private String requestStr;
-
- public String getRequestStr() {
- return requestStr;
- }
-
- public void setRequestStr(String requestStr) {
- this.requestStr = requestStr;
- }
- }
Response.java[java] view plain copy测试
- public class Response {
- private String responseStr;
-
- public String getResponseStr() {
- return responseStr;
- }
-
- public void setResponseStr(String responseStr) {
- this.responseStr = responseStr;
- }
- }
面向接口编程,编写过滤器接口。this
Filter.javaspa
[java] view plain copy.net
- public interface Filter {
- void doFilter(Request request, Response response, FilterChain chain);
- }
这里每次进行过滤后,都将过滤器链指向下一个过滤器,进行过滤,执行完后,再逐层返回,有点相似于递归。
编写过滤器链
FilterChain.java
[java] view plain copy
- import java.util.ArrayList;
- import java.util.List;
-
- public class FilterChain implements Filter{
- private List<Filter> filters = new ArrayList<>();
- private int index = 0;
-
- public FilterChain addFilter(Filter f){
- this.filters.add(f);
- return this;
- }
-
- @Override
- public void doFilter(Request request, Response response, FilterChain chain) {
- if(index == filters.size()) return;
-
- Filter f = filters.get(index);
- index ++;
- f.doFilter(request, response, chain);
- }
- }
该类中进行了两个操做,一个是过滤器的添加,一个是每一次过滤完成后,将索引加一后,再到下一个过滤器进行过滤,当走到尽头,再逐层返回。这有点相似于双向链表,先从头指针日后走,到了尽头再往前走。
编写两个过滤器类
HtmlFilter.java
[java] view plain copy
- public class HtmlFilter implements Filter {
- @Override
- public void doFilter(Request request, Response response, FilterChain chain) {
- request.setRequestStr(request.getRequestStr().replace('<', '[').replace('>', ']') + "---HtmlFilter");
- chain.doFilter(request, response, chain);
- response.setResponseStr(response.getResponseStr() + "---HtmlFilter");
- }
- }
将尖括号替换为中括号。
SeansitiveFilter.java
[java] view plain copy
- public class SensitiveFilter implements Filter {
- @Override
- public void doFilter(Request request, Response response,FilterChain chain) {
- request.setRequestStr(request.getRequestStr().replace("被就业", "就业").replace("敏感", "") + "---SensitiveFilter");
- chain.doFilter(request, response, chain);
- response.setResponseStr(response.getResponseStr() + "---SensitiveFilter");
- }
- }
去掉敏感词汇
最后编写测试用例
Main.java
[java] view plain copy
- public class Main {
- public static void main(String[] args) {
- String msg = "你们好:),<script>,敏感,被就业";
- Request request = new Request();
- request.setRequestStr(msg);
- Response response = new Response();
- response.setResponseStr("response");
-
- FilterChain fc = new FilterChain();
- fc.addFilter(new HtmlFilter()).addFilter(new SensitiveFilter());
- fc.doFilter(request, response, fc);
- System.out.println(request.getRequestStr());
- System.out.println(response.getResponseStr());
- }
- }
最终输出的结果为:[java] view plain copy
- 你们好:),[script],,就业---HtmlFilter---SensitiveFilter
- response---SensitiveFilter---HtmlFilter
若是由于某一缘由不进行接下来的过滤,则在FilterChain中加一个判断条件,在第几个过滤器不知足条件时,则不执行下一个过滤器的过滤,直接return便可,这样就直接返回了,response不会再进行相应过滤器的加工处理。