谷歌
一,一个初步的责任链模式的拦截器
拦截器接口
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