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; } }
Response:
package com.cy.dp.filter; public class Response { String responseStr; public String getResponseStr() { return responseStr; } public void setResponseStr(String responseStr) { this.responseStr = responseStr; } }
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()"; } }
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()"; } }
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()"; } }
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()