zoukankan      html  css  js  c++  java
  • 责任链设计模式

    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中。后续原理和上面 一样了就。

  • 相关阅读:
    sfs2x 连接 mongodb
    java websocket
    webstorm 4.0 注册码
    解决 sfs2 admin tool 找不到扩展
    window 注册表五大类
    opengl 学习第二日
    java google Protobuf
    扩展 java sencha touch PhonegapPlugin
    sencha touch2 kryonet socket phonegap 通信 作者:围城
    sencha touch2 layout 笔记
  • 原文地址:https://www.cnblogs.com/chengxuyuan-liu/p/10513130.html
Copyright © 2011-2022 走看看