背景:要把<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; } }