模拟场景:对一个request请求所带的信息进行三次过滤,并再返回response中加上过滤标记,第一次过滤html的特殊标记,并追加标记;第二次过滤敏感词,并追加标记;第三次替换表情,并追加标记。要求先一次过滤,在逆序的追加标签。这三个具体的过滤器类组成了一条责任链。
模拟request和response中的消息正文:
public class Request {
String reqStr;
public Request(String reqStr) {
this.reqStr = reqStr;
}
}
public class Response {
String resStr;
public Response(String resStr) {
this.resStr = resStr;
}
}
责任链中抽象的处理类设计:
public interface Filter {
public void doFilter(Request request, Response response, FilterChain chain);
}
具体处理类的设计,分别完成三次过滤:
public class HtmlFilter implements Filter {
//模拟过滤HTML标签
public void doFilter(Request request, Response response, FilterChain chain) {
request.reqStr = request.reqStr.replaceAll("<", "[").replaceAll(">", "]")+" +HtmlFilter+ ";
chain.doFilter(request, response, chain);
response.resStr += " +HtmlFilter+ ";
}
}
public class SensitiveFilter implements Filter {
//模拟过滤敏感词
public void doFilter(Request request, Response response, FilterChain chain) {
request.reqStr = request.reqStr.replaceAll("敏感词", "***") ;
chain.doFilter(request, response, chain);
response.resStr += " +SensitiveFilter+ ";
}
}
public class FaceFilter implements Filter {
//替换表情
public void doFilter(Request request, Response response, FilterChain chain) {
request.reqStr = request.reqStr.replaceAll(":\\)", "^~^");
chain.doFilter(request, response, chain);
response.resStr += " +FaceFilter+ ";
}
}
责任链的设计,从抽象的角度看,一条责任链同时也是一个过滤器,但是他还有组装各个过滤器的功能。他的具体执行处理方法(doFilter)从链中取出每个过滤器执行其具体的处理方法(doFilter),同时计数,当计数达到责任链中过滤器的数目时,不执行任何操作,直接返回。
public class FilterChain implements Filter{
private ArrayList<Filter> filters = new ArrayList<>();
private int index = 0;
public FilterChain addFilter(Filter filter){
filters.add(filter);
return this;
}
public void doFilter(Request request, Response response, FilterChain chain){
if(index == filters.size()) return;
Filter filter = filters.get(index);
index++;
filter.doFilter(request, response, chain);
}
}
客户端测试:
public class Client {
public static void main(String[] args) {
String msg = "大家好:) ,<script> <script> , 这是敏感词。";
Request request = new Request(msg);
Response response = new Response("response");
FilterChain fc1 = new FilterChain();
FilterChain fc2 = new FilterChain();
fc2.addFilter(new FaceFilter());
fc1.addFilter(new HtmlFilter()).addFilter(new SensitiveFilter()).addFilter(fc2);
fc1.doFilter(request, response, fc1);
System.out.println("过滤后的request消息正文:"+request.reqStr);
System.out.println("标记后的response消息正文:"+response.resStr);
}
}
***********结果************
过滤后的request消息正文:大家好^~^ ,[script] [script] , 这是***。
标记后的response消息正文response +FaceFilter+ +SensitiveFilter+ +HtmlFilter+
总结:整条责任链设计的巧妙之处在于,每个过滤器的doFilter()方法中都有一个责任链对象,每个过滤器都会调用该责任链对象的doFilter()方法,使得整条责任链可以继续执行下去,每个过滤器先处理request信息,在执行责任链,最后处理response信息。同时责任链类完成一个计数的功能,没有完成计数时,执行当前过滤器的doFilter()方法,计数完成时,直接返回,本质是利用了虚拟机的方法调整的栈来完成先处理request请求,在处理response的要求。