本文模擬一個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,什麼文件輸入流,有緩存的輸入流,字節型輸入流等,就是從不同的維度來處理輸入流的。
- 責任鏈也可以採用抽象類實現,大概思路,
- 抽象出一個類,包含處理請求的方法和返回下一個下家的引用。
- 具體工作類重寫處理請求的方法。