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

  • 相关阅读:
    路由器欺骗(原始套接字五)
    ICMP拒绝服务攻击(原始套接字系列四)
    ping的实现(原始套接字系列三)
    原始套接字基础(原始套接字系列二)
    原始套接字简介(原始套接字系列一)
    MMS服务学习
    转 Qt 翻译
    为应用程序设置一个图标 (窗口左上角 程序图标)
    正则表达式
    《TCP/IP详解 卷1:协议》第4章 ARP:地址解析协议
  • 原文地址:https://www.cnblogs.com/chengxuyuan-liu/p/10513130.html
Copyright © 2011-2022 走看看