责任链设计模式

自古美人都是妖i 提交于 2021-01-27 01:51:23

1.责任链模式   例如servlet中的filter struts2中的inceptor

应用场景:例如论坛的评论,在存入数据库之前要进行一系列的处理。例如影响页面显示的<>标签符号,敏感词汇等。可以通过一系列的过滤处理。

简单测试

package com.liuzhihong.simple;
/**
 * @ClassName Main
 * @Description
 * @Author 刘志红
 * @Date 2019/3/11
 **/
public class MessageProcessor {
    public static void main(String[] args) {
        String mas = "我是<蜡笔小新/>~~:敏感啊啊  啊 啊啊 啊";
        mas.replace("<", "[").replace("/>", "]").replace("敏感", "**");
        System.out.println(mas);
    }
}
View Code

我们这里是模拟,实际项目中处理逻辑没这么简单,可以好几百行代码,那么这么直接写肯定不满足我们面向对象的变成思想

进一步改造 

 接口 

package com.liuzhihong.simple.inter;
/**
 * @ClassName Filter
 * @Description
 * @Author 刘志红
 * @Date 2019/3/11
 **/
public interface Filter {
    String doFilter(String mas);
}
View Code 

两种实现

package com.liuzhihong.simple.imp;
import com.liuzhihong.simple.inter.Filter;
/**
 * @ClassName Filter1
 * @Description  模拟处理字符串把<转换为[
 * @Author 刘志红
 * @Date 2019/3/11
 **/
public class Filter1 implements Filter {
    @Override
    public String doFilter(String mas) {
          mas=mas.replace("<", "[").replace(">", "]");
          return mas;
    }
}
package com.liuzhihong.simple.imp;
import com.liuzhihong.simple.inter.Filter;
/**
 * @ClassName Filter2
 * @Description  模拟处理敏感词汇
 * @Author 刘志红
 * @Date 2019/3/11
 **/
public class Filter2 implements Filter {
    @Override
    public String doFilter(String mas) {
        mas=mas.replace("敏感", "**");
        return mas;
    }
}
View Code 

处理类 

package com.liuzhihong.simple.haddler;
import com.liuzhihong.simple.imp.Filter1;
import com.liuzhihong.simple.imp.Filter2;
import com.liuzhihong.simple.inter.Filter;
/**
 * @ClassName Main
 * @Description
 * @Author 刘志红
 * @Date 2019/3/11
 **/
public class MessageProcessor {
    private String massage;
    private Filter[] filters = {new Filter1(), new Filter2()};
    public String getMassage() {
        return massage;
    }
    public void setMassage(String massage) {
        this.massage = massage;
    }
    public String process() {
        for (Filter f :
                filters) {
            f.doFilter(massage);
        }
        return massage;
    }
}
View Code

测试类

package com.liuzhihong.simple;
import com.liuzhihong.simple.haddler.MessageProcessor;
/**
 * @ClassName Test
 * @Description
 * @Author 刘志红
 * @Date 2019/3/11
 **/
public class Test {
    public static void main(String[] args) {
        String mas = "我是<蜡笔小新/>~~:敏感啊啊  啊 啊啊 啊";
        MessageProcessor processor=new MessageProcessor();
        processor.setMassage(mas);
        String newMas = processor.process();
        System.out.println(newMas);
    }
}
View Code 

进一步添加需求:我们加入过滤规则,有的信息需要1,2过滤规则 但是有的信息需要1,2,3过滤规则,有的则需要1,3过滤规则 我们上面这么写显然不能满足需求了

  修改代码,进一步改造

 Filter接口和实现不变,添加过滤链FilteChain

package com.liuzhihong.simple.imp;
import com.liuzhihong.simple.inter.Filter;

import java.util.ArrayList;
import java.util.List;
/**
 * @ClassName FilterChain
 * @Description
 * @Author 刘志红
 * @Date 2019/3/11
 **/
public class FilterChain{
   private List<Filter> filters=new ArrayList<Filter>();
   public FilterChain addFilter(Filter f){
       this.filters.add(f);
       return this;
   }
    public String doFilter(String mas) {
        for (Filter f :
                filters) {
            mas=f.doFilter(mas);

        }
        return mas;
    }
}

修改MessageProcessor

package com.liuzhihong.simple.haddler;
import com.liuzhihong.simple.imp.Filter1;
import com.liuzhihong.simple.imp.Filter2;
import com.liuzhihong.simple.imp.FilterChain;
import com.liuzhihong.simple.inter.Filter;
/**
 * @ClassName Main
 * @Description
 * @Author 刘志红
 * @Date 2019/3/11
 **/
public class MessageProcessor {
    private Filter[] filters = {new Filter1(), new Filter2()};
    private String massage;
    private FilterChain filterChain;
    public FilterChain getFilterChain() {
        return filterChain;
    }
    public void setFilterChain(FilterChain filterChain) {
        this.filterChain = filterChain;
    }

    public String getMassage() {
        return massage;
    }
    public void setMassage(String massage) {
        this.massage = massage;
    }
//把处理过滤交给FilteChain处理 public String process() { massage=filterChain.doFilter(massage); return massage; } }

  测试类:

package com.liuzhihong.simple;
import com.liuzhihong.simple.haddler.MessageProcessor;
import com.liuzhihong.simple.imp.Filter1;
import com.liuzhihong.simple.imp.Filter2;
import com.liuzhihong.simple.imp.FilterChain;
/**
 * @ClassName Test
 * @Description
 * @Author 刘志红
 * @Date 2019/3/11
 **/
public class Test {
    public static void main(String[] args) {
        String mas = "我是<蜡笔小新/>~~:敏感啊啊  啊 啊啊 啊";
        FilterChain filterChain=new FilterChain();
        filterChain.addFilter(new Filter1()).addFilter(new Filter2());//我们可以根据实际需求添加需要的过滤即可满足需求
        MessageProcessor processor=new MessageProcessor();
        processor.setMassage(mas);
        processor.setFilterChain(filterChain);
        String newMas = processor.process();
        System.out.println(newMas);
    }
}

如果我们把FilteChain看成一个整体,假如我们的信息需要过滤过滤链1中的和过滤链中过滤所有过滤规则  只需要过滤链也实现Filter接口即可 

这是因为对于过滤链中的addFilter方法 Filter可以是过滤链也可以是过滤规则 他们都实现了Filter ,例如下面Filterchain1有两条规则,FilteChain2有两条规则

FilterChain1.add(FilterChain2) 这时候FilterChain1的List中的元素有3个 :过滤规则Filter1,过滤规则Filter2,过滤链FilterChain2,在运行到String newMas = processor.process();时候会调用通过

FilteChain的doFilter方法,这是后传入的是对象filterChain1。filterChain1中的List分别执行他们doFilter方法。Filter1,Filter2直接执行过滤massage,filterchain2执行doFilter方法时候,又调用FilteChain

的doFilter方法,这时候传入的是对象filterChain2,分别执行Filter3,Filter4的doFilter方法完成过滤。

修改代码,进一步改造

添加过滤规则Filter3去除信息中的空格

package com.liuzhihong.simple.imp;
import com.liuzhihong.simple.inter.Filter;
/**
 * @ClassName Filter3
 * @Description   去除空格
 * @Author 刘志红
 * @Date 2019/3/11
 **/
public class Filter3 implements Filter {
    @Override
    public String doFilter(String mas) {
        mas=mas.trim().replace(" ", "");
        return mas;
    }
}

添加过滤规则4在尾部添加感叹号

package com.liuzhihong.simple.imp;
import com.liuzhihong.simple.inter.Filter;
/**
 * @ClassName Filter4
 * @Description  在尾部加感叹号
 * @Author 刘志红
 * @Date 2019/3/11
 **/
public class Filter4 implements Filter {

    @Override
    public String doFilter(String mas) {
        mas = mas + "!";
        return mas;
    }
} 

测试类

package com.liuzhihong.simple;
import com.liuzhihong.simple.haddler.MessageProcessor;
import com.liuzhihong.simple.imp.*;
/**
* @ClassName Test
* @Description
* @Author 刘志红
* @Date 2019/3/11
**/
public class Test {
public static void main(String[] args) {
String mas = "我是<蜡笔小新/>~~:敏感啊啊 啊 啊啊 啊";
FilterChain filterChain1=new FilterChain();
filterChain1.addFilter(new Filter1()).addFilter(new Filter2());
FilterChain filterChain2=new FilterChain();
filterChain2.addFilter(new Filter3()).addFilter(new Filter4());
//FilteChain2中的过滤规则添加FilterChain1中
filterChain1.addFilter(filterChain2);
MessageProcessor processor=new MessageProcessor();
processor.setMassage(mas);
processor.setFilterChain(filterChain1);
String newMas = processor.process();
System.out.println(newMas);
}
}

 进一步改造 假如我们web项目中的请求和响应回来的信息都需要过滤

浏览器发出求情 通过过滤规则1 2 3 4的过滤 然后服务器接收响应 通过过滤规则4 3 2 1的过滤(图中的5 6 7 8)

代码如下:

过滤规则接口

package com.liuzhihong.simple.inter;
import com.liuzhihong.simple.web.Request;
import com.liuzhihong.simple.web.Response;
/**
 * @ClassName Filter
 * @Description
 * @Author 刘志红
 * @Date 2019/3/11
 **/
public interface Filter {
    void doFilter(Request request, Response response);
}
View Code

实现类过滤规则1

package com.liuzhihong.simple.imp;
import com.liuzhihong.simple.inter.Filter;
import com.liuzhihong.simple.web.Request;
import com.liuzhihong.simple.web.Response;
/**
 * @ClassName Filter1
 * @Description  模拟处理字符串把<转换为[
 * @Author 刘志红
 * @Date 2019/3/11
 **/
public class Filter1 implements Filter {

    @Override
    public void doFilter(Request request, Response response) {
        String requestMassage = request.getRequestMessage().replace("<", "[").replace(">", "]");
        requestMassage+="--request:filter1--";
        request.setRequestMessage(requestMassage);
    }
}
View Code

 

实现类过滤规则2

package com.liuzhihong.simple.imp;
import com.liuzhihong.simple.inter.Filter;
import com.liuzhihong.simple.web.Request;
import com.liuzhihong.simple.web.Response;
/**
 * @ClassName Filter2
 * @Description  模拟处理敏感词汇
 * @Author 刘志红
 * @Date 2019/3/11
 **/
public class Filter2 implements Filter {
    @Override
    public void doFilter(Request request, Response response) {
        String requestMessage = request.getRequestMessage().replace("敏感", "**");
        requestMessage+="--request:filter2--";
        request.setRequestMessage(requestMessage);
    }
}
View Code

 

实现类3过滤链 

package com.liuzhihong.simple.imp;
import com.liuzhihong.simple.inter.Filter;
import com.liuzhihong.simple.web.Request;
import com.liuzhihong.simple.web.Response;

import java.util.ArrayList;
import java.util.List;
/**
 * @ClassName FilterChain
 * @Description
 * @Author 刘志红
 * @Date 2019/3/11
 **/
public class FilterChain implements Filter{
   private List<Filter> filters=new ArrayList<Filter>();
   public FilterChain addFilter(Filter f){
       this.filters.add(f);
       return this;
   }
    public void  doFilter(Request request, Response response) {
        for (Filter f :
                filters) {
           f.doFilter(request, response);

        }
    }
}
View Code

模拟请求和响应

package com.liuzhihong.simple.web;
/**
 * @ClassName Server
 * @Description
 * @Author 刘志红
 * @Date 2019/3/11
 **/
public class Request {
    private String requestMessage;
    public String getRequestMessage() {
        return requestMessage;
    }
    public void setRequestMessage(String requestMessage) {
        this.requestMessage = requestMessage;
    }
}


package com.liuzhihong.simple.web;
/**
 * @ClassName Response
 * @Description
 * @Author 刘志红
 * @Date 2019/3/11
 **/
public class Response {
    private String responseMessage;
    public String getResponseMessage() {
        return responseMessage;
    }
    public void setResponseMessage(String responseMessage) {
        this.responseMessage = responseMessage;
    }
}
View Code

测试类

package com.liuzhihong.simple;
import com.liuzhihong.simple.imp.*;
import com.liuzhihong.simple.web.Request;
import com.liuzhihong.simple.web.Response;
/**
 * @ClassName Test
 * @Description
 * @Author 刘志红
 * @Date 2019/3/11
 **/
public class Test {
    public static void main(String[] args) {

        String mas = "我是<蜡笔小新/>~~:敏感啊啊  啊 啊啊 啊";
        Request request=new Request();
        request.setRequestMessage(mas);
        Response response=new Response();
        FilterChain filterChain=new FilterChain();
        filterChain.addFilter(new Filter1()).addFilter(new Filter2());
        filterChain.doFilter(request, response);
        System.out.println(request.getRequestMessage());
    }
}
View Code

 上面是请求添加过滤,那么响应怎么添加呢 如果我们直接在Filter1 Fiter2中添加的对响应的处理的话。执行结果如下:1 2 3 4。显然和我们想要的结果不符合,这也和实际逻辑矛盾 还没有响应过来信息就处理了---

那么我们该怎么处理呢 ,有点类似递归,一层一层进入,到底了满足一个条件然后一层一层退出

进一步改进代码:模拟请求和模拟响应类不变

过滤规则接口:

package com.liuzhihong.simple.inter;
import com.liuzhihong.simple.imp.FilterChain;
import com.liuzhihong.simple.web.Request;
import com.liuzhihong.simple.web.Response;
/**
 * @ClassName Filter
 * @Description
 * @Author 刘志红
 * @Date 2019/3/11
 **/
public interface Filter {
    void doFilter(Request request, Response response, FilterChain filterChain);
}
View Code

 

实现类

package com.liuzhihong.simple.imp;
import com.liuzhihong.simple.inter.Filter;
import com.liuzhihong.simple.web.Request;
import com.liuzhihong.simple.web.Response;
/**
 * @ClassName Filter1
 * @Description  模拟处理字符串把<转换为[
 * @Author 刘志红
 * @Date 2019/3/11
 **/
public class Filter1 implements Filter {

    @Override
    public void doFilter(Request request, Response response,FilterChain filterChain) {
        String requestMassage = request.getRequestMessage().replace("<", "[").replace(">", "]");
        requestMassage+="--request:filter1--";
        request.setRequestMessage(requestMassage);
        filterChain.doFilter(request, response, filterChain);
        String responseMessage = response.getResponseMessage().replace("<", "[").replace(">", "]");
        responseMessage+="--response:filter1--";
        response.setResponseMessage(responseMessage);
    }
}


package com.liuzhihong.simple.imp;
import com.liuzhihong.simple.inter.Filter;
import com.liuzhihong.simple.web.Request;
import com.liuzhihong.simple.web.Response;
/**
 * @ClassName Filter2
 * @Description  模拟处理敏感词汇
 * @Author 刘志红
 * @Date 2019/3/11
 **/
public class Filter2 implements Filter {
    @Override
    public void doFilter(Request request, Response response,FilterChain filterChain) {
        String requestMessage = request.getRequestMessage().replace("敏感", "**");
        requestMessage+="--request:filter2--";
        request.setRequestMessage(requestMessage);
        filterChain.doFilter(request, response, filterChain);
        String responseMessage = response.getResponseMessage().replace("敏感", "**");
        responseMessage+="--response:filter2--";
        response.setResponseMessage(responseMessage);
    }
}

package com.liuzhihong.simple.imp;
import com.liuzhihong.simple.inter.Filter;
import com.liuzhihong.simple.web.Request;
import com.liuzhihong.simple.web.Response;
import com.sun.xml.internal.bind.v2.model.core.ID;

import java.util.ArrayList;
import java.util.List;
/**
 * @ClassName FilterChain
 * @Description 过滤链
 * @Author 刘志红
 * @Date 2019/3/11
 **/
public class FilterChain implements Filter{
   private List<Filter> filters=new ArrayList<Filter>();
   private int index=0;
   public FilterChain addFilter(Filter f){
       this.filters.add(f);
       return this;
   }
    public void  doFilter(Request request, Response response,FilterChain filterChain) {
       if (index==filters.size())return;
        Filter filter = filters.get(index);
        index++;
        filter.doFilter(request, response, filterChain);
    }
}
View Code

 

测试类

package com.liuzhihong.simple;
import com.liuzhihong.simple.imp.*;
import com.liuzhihong.simple.web.Request;
import com.liuzhihong.simple.web.Response;
/**
 * @ClassName Test
 * @Description
 * @Author 刘志红
 * @Date 2019/3/11
 **/
public class Test {
    public static void main(String[] args) {

        String requestMas = "我是<request/>~~:敏感";
        String responseMas="我是<response/>~~:敏感";
        Request request=new Request();
        request.setRequestMessage(requestMas);
        Response response=new Response();
        response.setResponseMessage(responseMas);
        FilterChain filterChain=new FilterChain();
        filterChain.addFilter(new Filter1()).addFilter(new Filter2());
        filterChain.doFilter(request, response,filterChain);
        System.out.println(request.getRequestMessage());
        System.out.println(response.getResponseMessage());
    }
}
View Code

 Servlet之Filter原理:

容器把收到的请求和返回的响应封装成对应的Request,Response类,根据web.xml中Filter的配置信息(包括过滤规则的实现类和拦截域名)以及我们写的Filter(过滤规则),把请求,响应需要拦截处理的过滤规则存入FilterChain中。后续原理和上面 一样了就。

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!