文档章节

责任链设计模式应用场景示例(过滤器、拦截器)

凯文加内特
 凯文加内特
发布于 2016/04/19 10:06
字数 1105
阅读 491
收藏 6

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

先看一个问题:

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

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

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

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方法。

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

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

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);
    }
}


本文转载自:http://www.flyne.org/article/693

凯文加内特
粉丝 340
博文 698
码字总数 110557
作品 0
青岛
后端工程师
私信 提问
从源码角度理解Java设计模式——责任链模式

本文内容思维导图如下: 一、责任链模式介绍 责任链模式定义:为请求创建一个处理此请求对象的链。 适用场景(核心):只要把你的请求抛给第一个处理者,不用关心谁处理的,并且最终会返回你一个...

我叫刘半仙
2018/12/06
266
0
设计模式18——Chain of Responsibility设计模式

Chain of Responsibility(CoR)责任链设计模式是用一系列请求处理器试图处理一个请求,这些请求处理器之间是一个松散耦合,唯一的共同点是在他们之间传递请求。例如客户端发送一个请求,请求处...

小米米儿小
2014/01/26
146
0
JavaScript设计模式总结

之前看过《JavaScript设计模式与开发实践》这本书,对书中的设计模式和一些相关案例也有了一定的了解,同时把这些设计模式的应用对应在在一些其他的项目中,进行了一些整理,如下仅供参考: ...

jefferyE
03/26
0
0
Tomcat 系统架构与设计模式_ 设计模式分析

门面设计模式 门面设计模式在 Tomcat 中有多处使用,在 Request 和 Response 对象封装中、Standard Wrapper 到 ServletConfig 封装中、ApplicationContext 到 ServletContext 封装中等都用到...

lvzjane
2014/11/03
83
0
设计模式之责任链(ChainOfResponsibility)

责任链(ChainOfResponsibility) 对于设计模式的学习,一定要动手,而且要多次练习,然后慢慢消化和理解,才能明白其精髓。但是,设计模式只是在特殊情景下的特殊解决方案,不要滥用,不要为...

_-Leon-_
2014/06/11
2.5K
0

没有更多内容

加载失败,请刷新页面

加载更多

SpringBoot中 集成 redisTemplate 对 Redis 的操作(二)

SpringBoot中 集成 redisTemplate 对 Redis 的操作(二) List 类型的操作 1、 向列表左侧添加数据 Long leftPush = redisTemplate.opsForList().leftPush("name", name); 2、 向列表右......

TcWong
今天
5
0
排序––快速排序(二)

根据排序––快速排序(一)的描述,现准备写一个快速排序的主体框架: 1、首先需要设置一个枢轴元素即setPivot(int i); 2、然后需要与枢轴元素进行比较即int comparePivot(int j); 3、最后...

FAT_mt
昨天
4
0
mysql概览

学习知识,首先要有一个总体的认识。以下为mysql概览 1-架构图 2-Detail csdn |简书 | 头条 | SegmentFault 思否 | 掘金 | 开源中国 |

程序员深夜写bug
昨天
10
0
golang微服务框架go-micro 入门笔记2.2 micro工具之微应用利器micro web

micro web micro 功能非常强大,本文将详细阐述micro web 命令行的功能 阅读本文前你可能需要进行如下知识储备 golang分布式微服务框架go-micro 入门笔记1:搭建go-micro环境, golang微服务框架...

非正式解决方案
昨天
8
0
前端——使用base64编码在页面嵌入图片

因为页面中插入一个图片都要写明图片的路径——相对路径或者绝对路径。而除了具体的网站图片的图片地址,如果是在自己电脑文件夹里的图片,当我们的HTML文件在别人电脑上打开的时候图片则由于...

被毒打的程序猿
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部