設計模式(24)-----責任鏈模式-----攔截器設計模式
阿新 • • 發佈:2018-11-06
谷歌
一,一個初步的責任鏈模式的攔截器
攔截器介面
package com.DesignPatterns.an.Responsibility1; public interface Filter { String doFilter(String str); }
攔截器實現
package com.DesignPatterns.an.Responsibility1; public class HTMLFilter implements Filter { @Override public String doFilter(String str) {//process the html tag <> String r = str.replace('<', '[') .replace('>', ']'); return r; } }
package com.DesignPatterns.an.Responsibility1; public class SesitiveFilter implements Filter { @Override public String doFilter(String str) { String r= str.replace("被就業", "就業") .replace("敏感", ""); return r; } }
package com.DesignPatterns.an.Responsibility1; public class FaceFilter implements Filter { @Override public String doFilter(String str) { return str.replace(":)", "^V^"); } }
攔截器程式碼
package com.DesignPatterns.an.Responsibility1; public class MsgProcessor { private String msg; Filter[] filters = {new HTMLFilter(), new SesitiveFilter(), new FaceFilter()}; public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public String process() { String r=msg; for(Filter f:filters) { f.doFilter(r); } return r; } }
package com.DesignPatterns.an.Responsibility1; /** * 這個是責任鏈設計模式(攔截器設計模式)的入門 * @author qingruihappy * @data 2018年11月5日 下午11:48:05 * @說明:主要設計思路就是讓所有的攔截器都實現同樣的介面,讓後把所有的攔截器都放在一個list集合中來。 * 假如在加一個攔截器的話就會攔截器的process方法是不用變的,只需要在Filter[] filters的陣列中把已經實現了 * Filter介面的實現類加進來就行了。 * * 但是現在假如我們在攔截器的中間在加一組攔截器怎麼辦呢? */ public class Main { /** * @param args */ public static void main(String[] args) { String msg = "大家好:),<script>,敏感,被就業,網路授課沒感覺,因為看不見大家夥兒"; MsgProcessor mp = new MsgProcessor(); mp.setMsg(msg); String result = mp.process(); System.out.println(result); } }
大家好^V^,[script],,就業,網路授課沒感覺,因為看不見大家夥兒
二,平常我們看到的責任鏈的開發
package com.DesignPatterns.an.Responsibility2; public interface Filter { String doFilter(String str); }
package com.DesignPatterns.an.Responsibility2; public class HTMLFilter implements Filter { @Override public String doFilter(String str) { //process the html tag <> String r = str.replace('<', '[') .replace('>', ']'); return r; } }
package com.DesignPatterns.an.Responsibility2; public class SesitiveFilter implements Filter { @Override public String doFilter(String str) { //process the sensitive words String r = str.replace("被就業", "就業") .replace("敏感", ""); return r; } }
package com.DesignPatterns.an.Responsibility2; public class FaceFilter implements Filter { @Override public String doFilter(String str) { return str.replace(":)", "^V^"); } }
責任鏈模式的工具類
package com.DesignPatterns.an.Responsibility2; import java.util.ArrayList; import java.util.List; /** * * @author qingruihappy * @data 2018年11月6日 上午12:10:42 * @說明:這個類主要是用來新增過濾器及其便利過濾器的 */ public class FilterChain { List<Filter> filters = new ArrayList<Filter>(); /*注意這裡的用法,我們返回的是類本身,這樣我們就可以用fc.addFilter(new HTMLFilter()) .addFilter(new SesitiveFilter())這種責任鏈的編碼方式了。 ;*/ public FilterChain addFilter(Filter f) { this.filters.add(f); return this; } public String doFilter(String str) { String r = str; for(Filter f: filters) { r = f.doFilter(r); } return r; } }
package com.DesignPatterns.an.Responsibility2; /** * 這個類主要是用來呼叫FilterChain的 * @author qingruihappy * @data 2018年11月6日 上午12:11:34 * @說明: */ public class MsgProcessor { private String msg; FilterChain fc; public FilterChain getFc() { return fc; } public void setFc(FilterChain fc) { this.fc = fc; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public String process() { return fc.doFilter(msg); } }
package com.DesignPatterns.an.Responsibility2; public class Main { /** * @param args */ public static void main(String[] args) { String msg = "大家好:),<script>,敏感,被就業,網路授課沒感覺,因為看不見大家夥兒"; MsgProcessor mp = new MsgProcessor(); mp.setMsg(msg); FilterChain fc = new FilterChain(); fc.addFilter(new HTMLFilter()) .addFilter(new SesitiveFilter()) .addFilter(new FaceFilter()); mp.setFc(fc); String result = mp.process(); System.out.println(result); } }
大家好^V^,[script],,就業,網路授課沒感覺,因為看不見大家夥兒
三,在一組責任鏈中加入另一組責任鏈
package com.DesignPatterns.an.Responsibility3; public interface Filter { String doFilter(String str); }
package com.DesignPatterns.an.Responsibility3; public class HTMLFilter implements Filter { @Override public String doFilter(String str) { //process the html tag <> String r = str.replace('<', '[') .replace('>', ']'); return r; } }
package com.DesignPatterns.an.Responsibility3; public class SesitiveFilter implements Filter { @Override public String doFilter(String str) { //process the sensitive words String r = str.replace("被就業", "就業") .replace("敏感", ""); return r; } }
package com.DesignPatterns.an.Responsibility3; public class FaceFilter implements Filter { @Override public String doFilter(String str) { return str.replace(":)", "^V^"); } }
package com.DesignPatterns.an.Responsibility3; import java.util.ArrayList; import java.util.List; public class FilterChain implements Filter { List<Filter> filters = new ArrayList<Filter>(); /*注意這裡的用法,我們返回的是類本身,這樣我們就可以用fc.addFilter(new HTMLFilter()) .addFilter(new SesitiveFilter())這種責任鏈的編碼方式了。 ;*/ public FilterChain addFilter(Filter f) { this.filters.add(f); return this; } public String doFilter(String str) { String r = str; for(Filter f: filters) { r = f.doFilter(r); } return r; } }
package com.DesignPatterns.an.Responsibility3; public class MsgProcessor { private String msg; FilterChain fc; public FilterChain getFc() { return fc; } public void setFc(FilterChain fc) { this.fc = fc; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public String process() { return fc.doFilter(msg); } }
package com.DesignPatterns.an.Responsibility3; /** * 這裡主要注意的是在一組攔截器中加入另一組攔截器的 * @author qingruihappy * @data 2018年11月6日 上午12:15:36 * @說明: */ public class Main { /** * @param args */ public static void main(String[] args) { String msg = "大家好:),<script>,敏感,被就業,網路授課沒感覺,因為看不見大家夥兒"; MsgProcessor mp = new MsgProcessor(); mp.setMsg(msg); FilterChain fc = new FilterChain(); fc.addFilter(new HTMLFilter()) .addFilter(new SesitiveFilter()) ; //注意在這裡讓FilterChain也去實現Filter介面,它按照黑盒的思路來看的話其實就是 //另一個數組,直接在原來的陣列中加入另一個數組就行了。看下面的實現。 FilterChain fc2 = new FilterChain(); fc2.addFilter(new FaceFilter()); fc.addFilter(fc2); mp.setFc(fc); String result = mp.process(); System.out.println(result); } }
四,請求責任鏈攔截,返回責任鏈攔截,並且是先進後出的堆疊模式
package com.DesignPatterns.an.Responsibility4; public class Request { String requestStr; public String getRequestStr() { return requestStr; } public void setRequestStr(String requestStr) { this.requestStr = requestStr; } }
package com.DesignPatterns.an.Responsibility4; public class Response { String responseStr; public String getResponseStr() { return responseStr; } public void setResponseStr(String responseStr) { this.responseStr = responseStr; } }
package com.DesignPatterns.an.Responsibility4; public interface Filter { void doFilter(Request request, Response response, FilterChain chain); }
package com.DesignPatterns.an.Responsibility4; public class HTMLFilter implements Filter { @Override public void doFilter(Request request, Response response, FilterChain chain) { //process the html tag <> request.requestStr = request.requestStr.replace('<', '[') .replace('>', ']') + "---HTMLFilter()"; chain.doFilter(request, response, chain); response.responseStr += "---HTMLFilter()"; } }
package com.DesignPatterns.an.Responsibility4; public class SesitiveFilter implements Filter { @Override public void doFilter(Request request, Response response, FilterChain chain) { request.requestStr = request.requestStr.replace("被就業", "就業") .replace("敏感", "") + "---SesitiveFilter()"; chain.doFilter(request, response, chain); response.responseStr += "---SesitiveFilter()"; } }
package com.DesignPatterns.an.Responsibility4; import java.util.ArrayList; import java.util.List; public class FilterChain implements Filter { List<Filter> filters = new ArrayList<Filter>(); 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); } }
package com.DesignPatterns.an.Responsibility4; /** * * @author qingruihappy * @data 2018年11月6日 上午12:23:38 * @說明:這個主要處理的就是有請求有返回的,而且要遵循先進後出的邏輯堆疊的邏輯 * 這裡主要用到了遞迴的方法。其實也簡單 * 我們來寫一下它的思路 * 1:我們先把HTMLFilter,SesitiveFilter兩個過濾器載入到過濾器鏈中。 * 2:呼叫FilterChain的doFilter方法,我們初始化index的索引是0,這個時候index++之後就會變成1,而現在我們get(0)的時候就會獲取到 * HTMLFilter的doFilter方法,執行HTMLFilter裡面的替換的方法。 * 3,當在HTMLFilter執行完之後會執行FilterChain裡面的doFilter的方法,因為這個時候index是1了,這個時候會把index++後設置成2,讓後執行 * SesitiveFilter裡面的doFilter方法,在執行完SesitiveFilter裡面的替換的方法之後。 * 4,接著呼叫FilterChain裡面的doFilter的方法,這個時候發現index是2了就會返回 * 5,首先它會遵循方法堆疊中的先進後出的原則,回到SesitiveFilter類中執行response的相關程式碼 * 6,然後在回到HTMLFilter類中執行response的方法 */ public class Main { /** * @param args */ 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 SesitiveFilter()) ; fc.doFilter(request, response, fc); System.out.println(request.getRequestStr()); System.out.println(response.getResponseStr()); } }
大家好:),[script],,就業,網路授課沒感覺,因為看不見大家夥兒---HTMLFilter()---SesitiveFilter()
response---SesitiveFilter()---HTMLFilter()
五,servlet過濾器的一覽
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { /* 在訪問的時候執行 */ System.out.println("======= 開始執行doFilter ========"); // 轉發到下一個元件,進行後續的處理(元件可以是一個過濾器,也可以是一個servlet) chain.doFilter(request, response); System.out.println("======= 結束執行doFilter ========"); }
是不是很像啊,假如有多個過濾器的話那麼我們就在xml檔案中進行多個配置
如下面的。
import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class BasicsFilter implements Filter { public BasicsFilter() { // 容器(伺服器)啟動時執行 } /** * @see Filter#init(FilterConfig) */ public void init(FilterConfig fConfig) throws ServletException { /* 容器(伺服器)時執行 */ System.out.println("======== 初始化方法 ========"); // 獲取的是web.xml中配置Filter時設定的值,引數為設定值得名稱,若引數不存在,則返回空 String initParam = fConfig.getInitParameter("param"); System.out.println("param ========" + initParam); } /** * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { /* 在訪問的時候執行 */ System.out.println("======= 開始執行doFilter ========"); // 轉發到下一個元件,進行後續的處理(元件可以是一個過濾器,也可以是一個servlet) chain.doFilter(request, response); System.out.println("======= 結束執行doFilter ========"); } /** * @see Filter#destroy() */ public void destroy() { // TODO Auto-generated method stub } }
import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class otherFilter implements Filter { public otherFilter() { // 容器(伺服器)啟動時執行 } /** * @see Filter#init(FilterConfig) */ public void init(FilterConfig fConfig) throws ServletException { /* 容器(伺服器)時執行 */ System.out.println("======== 初始化方法 ========"); // 獲取的是web.xml中配置Filter時設定的值,引數為設定值得名稱,若引數不存在,則返回空 String initParam = fConfig.getInitParameter("param"); System.out.println("param ========" + initParam); } /** * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { /* 在訪問的時候執行 */ System.out.println("======= 開始執行doFilter ========"); // 轉發到下一個元件,進行後續的處理(元件可以是一個過濾器,也可以是一個servlet) chain.doFilter(request, response); System.out.println("======= 結束執行doFilter ========"); } /** * @see Filter#destroy() */ public void destroy() { // TODO Auto-generated method stub } }
在下面的xml中有兩個攔截器,它是按照在xml中的順序執行的。從這裡我們不難看出,誰在前面就會先通過xml的解析jar包把誰載入到list或者陣列中來,這樣的話就會先執行誰,是不是和我們上面4的案例很像呢。
<filter> <filter-name>basicsFilter</filter-name> <filter-class>com.hudongwu.filter.BasicsFilter</filter-class> <init-param><!-- 設定在過濾器中執行初始化方法時,獲取的值 --> <param-name>param</param-name> <param-value>studyFilter</param-value> </init-param> </filter> <filter> <filter-name>otherFilter</filter-name> <filter-class>com.hudongwu.filter.otherFilter</filter-class> <init-param><!-- 設定在過濾器中執行初始化方法時,獲取的值 --> <param-name>param</param-name> <param-value>otherFilter</param-value> </init-param> </filter> <filter-mapping> <filter-name>basicsFilter</filter-name> <!-- 設定為訪問該網站所有地址都需要通過該過濾器 --> <url-pattern>/*</url-pattern> <!-- 設定為只有訪問該網站的/Helloword地址時才通過該過濾器 --> <url-pattern>/Helloword</url-pattern> </filter-mapping> <filter-mapping> <filter-name>otherFilter</filter-name> <!-- 設定為訪問該網站所有地址都需要通過該過濾器 --> <url-pattern>/*</url-pattern> <!-- 設定為只有訪問該網站的/otherFilter地址時才通過該過濾器 --> <url-pattern>/otherFilter</url-pattern> </filter-mapping>
ll