• 责任链设计模式(过滤器、拦截器)


    责任链设计模式(Chain of Responsibility)的应用有:Java Web中的过滤器链、Struts2中的拦截器栈。

    先看一个问题:

    给定一个字符串“被就业了:),敏感信息,<script>”,对其中的HTML标记和敏感词进行过滤或替换。
    本文主要以该问题设计方法的演变来讲解责任链设计模式。

    第一种设计:没有任何设计模式

    设计了一个MsgProcessor类,完成字符串处理的主要工作。MainClass类是本设计中的测试类。

    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    public class MainClass {
        public static void main(String[] args) {
            //需要被过滤的语句
            String msg = "被就业了:),敏感信息,<script>";
     
            //实例化处理类
            MsgProcessor mp = new MsgProcessor(msg);
            String r = mp.process();
     
            System.out.println(r);
        }
     
    }
     
    public class MsgProcessor {
        private String msg;
        public MsgProcessor(String msg){
            this.msg = msg;
        }
     
        public String process(){
            String r = msg;
            //过滤msg中的HTML标记
            r = r.replace("<", "&lt;").replace(">", "&gt;");
            //过滤敏感词
            r = r.replace("敏感", "").replace("被就业", "就业");
     
            return r;
        }
    }

    第二种设计:增加一个Filter接口

    在第一种设计中,对字符串的所有处理都放在MsgProcessor类中,扩展性极差。如果要过滤字符串中的笑脸(将”:)”替换成”^_^”),则需要改动MSgProcessor中的process方法。

    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    public interface Filter {
        String doFilter(String str);
    }
     
    public class HtmlFilter implements Filter {
        public String doFilter(String msg) {
            String r = msg;
            //过滤msg中的HTML标记
            r = r.replace("<", "&lt;").replace(">", "&gt;");
     
            return r;
        }
    }
     
    public class SensitiveFilter implements Filter {
        public String doFilter(String msg) {
            String r = msg;
            //过滤敏感词
            r = r.replace("敏感", "").replace("被就业", "就业");
     
            return r;
        }
    }
     
    public class MsgProcessor {
        private String msg;
        private Filter[] filters = {new HtmlFilter(),new SensitiveFilter()};
     
        public MsgProcessor(String msg){
            this.msg = msg;
        }
     
        public String process(){
            String r = msg;
            for(Filter f : filters){
                r = f.doFilter(r);
            }
            return r;
        }
    }

    此时,如果需要过滤字符串中的笑脸,只需要创建一个类FaceFilter实现Filter接口,并在MsgProcessor类中的filters字段中登记即可。

    第三种设计:责任链模式(FilterChain)

    定义:将一个事件处理流程分派到一组执行对象上去,这一组执行对象形成一个链式结构,事件处理请求在这一组执行对象上进行传递。责任链模式的主要参与角色:

    ① 事件处理请求对象(Request)

    ② 执行对象(Handler)

    责任链设计模式(过滤器、拦截器)1838

    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    public class FilterChain implements Filter {
     
        public List<Filter> filters= new ArrayList<Filter>();
     
        public FilterChain addFilter(Filter f){
            filters.add(f);
            return this;
        }
     
        public String doFilter(String msg) {//执行filters中的doFilter方法即可
            String r = msg;
            for(Filter f : filters){
                r = f.doFilter(r);
            }
            return r;
        }
    }
     
    public class MsgProcessor {
        private String msg;
        private FilterChain chain = new FilterChain();
     
        public MsgProcessor(String msg,Filter Chain){
            this.msg = msg;
            this.chain = chain;
        }
     
        public String process(){
            return chain.doFilter(msg);
        }
    }
     
    public class MainClass {
        public static void main(String[] args) {
            //需要被过滤的语句
            String msg = "被就业了:),敏感信息,<script>";
     
            //搞一个过过滤链
            FilterChain chain = new FilterChain();
            chain.addFilter(new HtmlFilter()).addFilter(new SensitiveFilter());
            //实例化处理类
            MsgProcessor mp = new MsgProcessor(msg,chain);
            String r = mp.process();
     
            System.out.println(r);
        }
    }

    责任链模式加强版
    上面的实现的过滤链可以用下图a)表示出来,整个过程只对msg过滤了一次。而JavaWeb中的过滤器链和Struts2中的拦截器栈执行的过程可以形象的表示为图b,☆很重要)。

    责任链设计模式(过滤器、拦截器)2890

    下面用程序模拟JavaWeb中的过滤器,实现类似于对Request和Response的过滤。主要涉及的类如下所示:

    责任链设计模式(过滤器、拦截器)2950

    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    public interface Filter {
        void doFilter(Request req,Response resp,FilterChain chain);
    }
     
    public class HtmlFilter implements Filter {
        public void doFilter(Request req, Response resp, FilterChain chain) {
            //过滤req.reqStr中的HTML标记
            req.reqStr = req.reqStr.replace("<", "&lt;").replace(">", "&gt;");
            req.reqStr += "---HtmlFilter()---";
            chain.doFilter(req, resp);
            resp.respStr += "---HtmlFilter()---";
        }
    }
     
    public class SensitiveFilter implements Filter {
        public void doFilter(Request req, Response resp, FilterChain chain) {
            // 过滤req.reqStr中的敏感词
            req.reqStr = req.reqStr.replace("敏感", "").replace("被就业", "就业");
            req.reqStr += "===SensitiveFilter";
            chain.doFilter(req, resp);
            resp.respStr += "===SensitiveFilter";
        }
    }
     
    public class FilterChain{
        private List<Filter> filters = new ArrayList<Filter>();
        //调用链上的过滤器时,记录过滤器的位置用
        private int index = 0;
     
        public FilterChain addFilter(Filter f){
            filters.add(f);
            return this;
        }
     
        public void doFilter(Request req, Response resp) {
            if(index == filters.size()) return;
            //得到当前过滤器
            Filter f = filters.get(index);
            index++;
     
            f.doFilter(req, resp, this);
        }
    }
     
    public class Request {
        //在Request中只保持了一个reqStr字段记录对Request的操作
        //为了方便模拟,没有将reqStr设置为private
        String reqStr;
    }
     
    public class Response {
        //在Response中只保持了一个respStr字段记录对Response的操作
        //为了方便模拟,没有将respStr设置为private
        String respStr;
    }
    package org.flyne.fiter;
     
    public class MainClass {
        public static void main(String[] args) {
            // 需要被过滤的语句
            String msg = "被就业了:),敏感信息,<script>";
     
            //创建Request、Response对象
            Request req = new Request();
            Response resp = new Response();
            req.reqStr = msg;
            resp.respStr = "response";
     
            //搞一个过滤链,链上有两个过滤器
            FilterChain chain = new FilterChain();
            chain.addFilter(new HtmlFilter())
                .addFilter(new SensitiveFilter());
     
            //开始过滤
            chain.doFilter(req, resp);
     
            System.out.println(req.reqStr);
            System.out.println(resp.respStr);
        }
    }
  • 相关阅读:
    linux时间同步ntp服务的安装与配置
    linux系统的初化始配置
    透明手机
    linux桌面的安装
    Linux中FTP服务器的搭建教程
    Linux怎样创建FTP服务器--修改用户默认目录-完美解决
    linux下vsftpd的安装及配置
    vsftpd快速部署_2018_lcf
    史上最详细的vsftpd配置文件详解2
    史上最详细的vsftpd配置文件讲解
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/4139306.html
Copyright © 2020-2023  润新知