tomcat責任鏈模式

本文模擬一個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)
    這幾處代碼。
  • 也有單向的責任鏈,實現起來相對簡單。
  • 責任鏈的兩種劃分,
    1. 內置責任鏈,鏈中的各個環節都有對下家的引用,其實是個棧。
    2. 外置責任鏈,單獨維護一個鏈條,每個環節都不知道自己的下家。
  • 責任鏈和裝飾者的比較,
    1. 裝飾者更像是內置鏈條的責任鏈。但就我所使用的情況看,責任鏈通常是有預定義的鏈條的;而裝飾者更多的是根據實際情況自定義裝飾、處理順序的。
    2. 裝飾者的每一層裝飾,都是從不同維度來完成一項工作。比如著名的java中的inputstream,什麼文件輸入流,有緩存的輸入流,字節型輸入流等,就是從不同的維度來處理輸入流的。
  • 責任鏈也可以採用抽象類實現,大概思路,
    1. 抽象出一個類,包含處理請求的方法和返回下一個下家的引用。
    2. 具體工作類重寫處理請求的方法。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章