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不會再進行相應過濾器的加工處理。