设计模式(24)-----责任链模式-----拦截器设计模式

谷歌

 一,一个初步的责任链模式的拦截器

拦截器接口

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

猜你喜欢

转载自www.cnblogs.com/qingruihappy/p/9912527.html
今日推荐