有這樣一個應用場景,對於傳入后台的Request和返回頁面的Response信息,如果頁面的Request帶有敏感信息或危險字符串,就會對系統造成影響,所以我們會寫過濾器(Filter)處理Request,不同的信息處理會有不同的處理方式,如果我們只用一個Filter來處理所有的信息,擴展性就不夠強,所以會針對不同的信息處理寫不同的Filter,然后把Filter放在一個FilterChain中,以實現信息處理的“熱拔插”,這樣一個FilterChain就像一條職責鏈,鏈上的每個節點處理不同的功能,同時對於Response我們希望能以Resuest處理的倒序進行返回處理,以達到完全過濾敏感信息的效果,功能圖如下所示。

AFilter到DFilter構成了一個FilterChain。
現在來模擬這個Servlet中的FilterChain。
首先定義接口Filter,因為所有的Filter必須遵循這個規范,才能裝載在FilterChain中。
1 public interface Filter { 2 void doFilter(Request request,Response response,FilterChain chain); 3 }
接下來,編寫FilterChain以及各個Filter。
1 public class FilterChain implements Filter{ 2 List<Filter> fs = new ArrayList<Filter>(); 3 int index = 0; 4 5 6 public FilterChain addFilter(Filter f) { 7 fs.add(f); 8 return this; 9 } 10 11 12 @Override 13 public void doFilter(Request request, Response response,FilterChain chain) { 14 if(index == fs.size()) return; 15 Filter f = fs.get(index); 16 index ++; 17 f.doFilter(request, response, chain); 18 } 19 20 21 }
1 public class HTMLFilter implements Filter { 2 3 4 @Override 5 public void doFilter(Request request, Response response,FilterChain chain) { 6 request.requestStr = request.requestStr.replace("<", "[").replace(">", "]") + "--HTML--"; 7 chain.doFilter(request, response, chain); 8 response.responseStr += "--HTML--"; 9 } 10 }
1 public class SensitiveFilter implements Filter { 2 3 4 @Override 5 public void doFilter(Request request, Response response,FilterChain chain) { 6 request.requestStr = request.requestStr.replace("被就業", "就業").replace("敏感", "**") + "--Sensitive--"; 7 chain.doFilter(request, response, chain); 8 response.responseStr += "--Sensitive--"; 9 } 10 11 12 }
最后測試類。
1 public class Test { 2 3 /** 4 * @param args 5 */ 6 public static void main(String[] args) { 7 String msg = "測試,<script>,被就業,敏感信息"; 8 FilterChain fc = new FilterChain(); 9 fc.addFilter(new HTMLFilter()).addFilter(new SensitiveFilter()); 10 Request request = new Request(); 11 request.setRequestStr(msg); 12 Response response = new Response(); 13 response.setResponseStr("response"); 14 fc.doFilter(request, response,fc); 15 System.out.println(request.getRequestStr()); 16 System.out.println(response.getResponseStr()); 17 } 18 19 }
測試結果如下(箭頭為Filter走向):

