java设计模式-责任链

背景:要把<script>等<>html标签替换掉;把敏感词屏蔽或者替换等;
1.刚开始可能这么写:                    
public class Main {

    public static void main(String[] args) {
        String msg = "大家好:),<script>,敏感,被就业,撒的合法了思考的环境法拉盛看到回复";
        MsgProcessor mp = new MsgProcessor();
        mp.setMsg(msg);
        String result = mp.processor();
        System.out.println(result);
        
    }

}
public class MsgProcessor {
    private String msg;
    
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    
    public String processor(){
        //process the html tag<>
        String r = msg.replace('<', '[').replace('>', ']');
        //process the sensitive words
        r = r.replace("被就业", "就业")
             .replace("敏感","");
        return r;
    }
    
}

但是上面写的缺点:

如果还有其他的逻辑,其他的替换,那么又要在processor里面写其他的替换法则,不利于扩展;

 

2.于是换成下面写法:                  

定义接口Filter:

public interface Filter {
    
    String doFilter(String str);
    
}

处理html tag的类:

public class HTMLFilter implements Filter {
    @Override
    public String doFilter(String str) {
        //process the html tag<>
        String r = str.replace('<', '[').replace('>', ']');
        return r;
    }
}

处理敏感词的类:

public class SensitiveFilter implements Filter {

    @Override
    public String doFilter(String str) {
        //process the sensitive words
        String    r = str.replace("被就业", "就业")
                       .replace("敏感","");
        return r;
    }

}

MsgProcessor:

public class MsgProcessor {
    private String msg;
    private Filter[] filters = {new HTMLFilter(), new SensitiveFilter()};
    
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    
    public String processor(){
        String r = msg;
        
        for(Filter f : filters){
            r = f.doFilter(r);
        }
        
        return r;
    }
}

运行测试main,正确得到结果;

这样做的好处是:

新添加的规则可以放在filters数组的任意顺序上;

新添加的过滤规则可以任意扩展,只要实现Filter接口,并且实现方法,再添加进filters数组就可以了;

 

但是现在考虑一个问题:

如果已经存在一个过滤器链了,要想把这整个过滤器链加到原来的逻辑里面,怎么做呢?

 

 

3.修改为如下:              

FilterChain.java:

public class FilterChain implements Filter{
    List<Filter> filters = new ArrayList<Filter>();
    
    public FilterChain addFilter(Filter f){
        this.filters.add(f);
        return this;
    }
    
    public String doFilter(String str){
        String r = str;
        
        for(Filter f: filters){
            r = f.doFilter(r);
        }
        return r;
    }
}

MsgProcessor:

public class MsgProcessor {
    private String msg;
    private FilterChain fc;
    
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    public FilterChain getFc() {
        return fc;
    }
    public void setFc(FilterChain fc) {
        this.fc = fc;
    }
    
    public String processor(){
        return fc.doFilter(this.msg);
    }
}

Main:

public class Main {

    public static void main(String[] args) {
        String msg = "大家好:),<script>,敏感,被就业,撒的合法了思考的环境法拉盛看到回复";
        MsgProcessor mp = new MsgProcessor();
        FilterChain fc = new FilterChain();
        //设置好过滤规则链
        fc.addFilter(new HTMLFilter())
          .addFilter(new FaceFilter());
        
        FilterChain fc2 = new FilterChain();
        fc2.addFilter(new SensitiveFilter());
        
        fc.addFilter(fc2);
        
        mp.setMsg(msg);
        mp.setFc(fc);
        
        String result = mp.processor();
        System.out.println(result);
        
    }

}

运行main,打印:

大家好^_^,[script],,就业,撒的合法了思考的环境法拉盛看到回复

 

4.既处理发送到服务端,也处理从服务端返回到客户端:            

现在只是消息从一头发往另一头进行的过滤,而现实之中往往是消息从客户端发往服务器端,服务器端也有一个反馈,
现在想做这样一个过滤器,既可以过滤从客户端发往服务器端的消息,也可以过滤从服务器端返回来的消息;
怎么做呢?
正如struts2的interceptor和tomcat等容器的filter都是这样做的;既处理过去的消息,也处理回来的消息;
 
把request、response交给过滤器的话,过滤器既能把request对象处理,也能把response对象处理掉;
处理request的过滤器的顺序和处理response的过滤器的顺序正好是相反的:
这里简单使用Request中包含一个string、Response中包含一个string来简单模拟:

上代码:

Request:

package com.cy.dp.filter;

public class Request {
    String requestStr;

    public String getRequestStr() {
        return requestStr;
    }

    public void setRequestStr(String requestStr) {
        this.requestStr = requestStr;
    }
}
View Code

Response:

package com.cy.dp.filter;

public class Response {
    String responseStr;

    public String getResponseStr() {
        return responseStr;
    }
    public void setResponseStr(String responseStr) {
        this.responseStr = responseStr;
    }
}
View Code

Filter:

package com.cy.dp.filter;

public interface Filter {
    
    void doFilter(Request request, Response response, FilterChain chain);
    
}

HTMLFilter:

package com.cy.dp.filter;

public class HTMLFilter implements Filter {

    @Override
    public void doFilter(Request request, Response response, FilterChain chain) {
        //process the html tag<>
        request.requestStr = request.requestStr.replace('<', '[').replace('>', ']') + "----HTMLFilter()";
        chain.doFilter(request, response, chain);
        
        response.responseStr += "----HTMLFilter()";
    }
    
    
}
View Code

SensitiveFilter:

package com.cy.dp.filter;

public class SensitiveFilter implements Filter {

    @Override
    public void doFilter(Request request, Response response, FilterChain chain) {
        
        //process the sensitive words
        request.requestStr = request.requestStr.replace("被就业", "就业").replace("敏感","") + "----SensitiveFilter()";
        chain.doFilter(request, response, chain);
        
        response.responseStr += "----SensitiveFilter()";
    }

}
View Code

FaceFilter:

package com.cy.dp.filter;

public class FaceFilter implements Filter {
    
    @Override
    public void doFilter(Request request, Response response, FilterChain chain) {
        //process the face
        request.requestStr = request.requestStr.replace(":)", "^_^") + "----FaceFilter()";
        chain.doFilter(request, response, chain);
        
        response.responseStr += "----FaceFilter()";
    }
}
View Code

FilterChain:

package com.cy.dp.filter;

import java.util.ArrayList;
import java.util.List;

public class FilterChain implements Filter{
    List<Filter> filters = new ArrayList<Filter>();
    int index = 0;
    
    public FilterChain addFilter(Filter f){
        this.filters.add(f);
        return this;
    }

    @Override
    public void doFilter(Request request, Response response, FilterChain chain) {
        if(index==filters.size()) return;
        
        Filter f = filters.get(index);
        index ++;
        f.doFilter(request, response, chain);
    }
}

测试代码Main:

package com.cy.dp.filter;

public class Main {

    public static void main(String[] args) {
        String msg = "大家好:),<script>,敏感,被就业,撒的合法了思考的环境法拉盛看到回复";
        Request request = new Request();
        request.setRequestStr(msg);
        Response response = new Response();
        response.setResponseStr("response");
        
        //设置好过滤规则链
        FilterChain fc = new FilterChain();
        fc.addFilter(new HTMLFilter())
          .addFilter(new SensitiveFilter())
          .addFilter(new FaceFilter());
          
        
        fc.doFilter(request, response, fc);
        
        System.out.println(request.getRequestStr());
        System.out.println(response.getResponseStr());
    }

}

运行结果:

大家好^_^,[script],,就业,撒的合法了思考的环境法拉盛看到回复----HTMLFilter()----SensitiveFilter()----FaceFilter()
response----FaceFilter()----SensitiveFilter()----HTMLFilter()

 

 

 

 

 

posted on 2018-05-24 00:04  有点懒惰的大青年  阅读(746)  评论(0编辑  收藏  举报