责任链模式:使多个对象都有机会处理请求,从而避免请求的送发者和接收者之间的耦合关系 。
形象的理解,将一个逻辑处理的过程封装成filter接口,然后根据需求创建不同的filter,为了filter之间能顺序处理并且可以随意拼接组合,将多个filter设置成ArrayList并且封装在fliterChain,这样只需将不同的filter add进FilterChain中,然后根据add进FilterChain中的顺序dofilter()传进的对象参数,这相当于一个Request的过程。
而Respone是一个逆序的过程,怎么样按照添加filter的顺序,自动的将请求逆序的返回回来呢?
只需将FilterChain实例作为参数FilterChain的doFilter()的参数,即每次调用都将自己携带,因此每次在Filter的doFilter方法中过滤处理一次后就继续调用chain中的doFilter方法,而在chainFilter对于已处理的Filter进行计数,一旦到达添加的Filter Size以后就return ,返回的时候 会递归定位到到上一次在Filter内部调用chain的doFilter()后续代码继续执行,此处的代码就可以设置成reponse的处理,而返回的顺序正好是request进来的顺序的逆序。此种处理逻辑和方法与struct中intercepter拦截器的原理一样,可以见我之前写的这个帖子:点击打开链接
下面附上代码:
过滤器接口:
package JavaWebFilter;
public interface Filter {
void doFilter(Request request, Response response, FilterChain chain);
}
过滤器具体类:
htmlFilter:
package JavaWebFilter;
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()";
}
}
senstiveFilter:
package JavaWebFilter;
public class SesitiveFilter implements Filter {
@Override
public void doFilter(Request request, Response response, FilterChain chain) {
request.requestStr = request.requestStr.replace("被就业", "就业")
.replace("敏感", "") + "---SesitiveFilter()";
chain.doFilter(request, response, chain);
response.responseStr += "---SesitiveFilter()";
}
}
过滤链:
package JavaWebFilter;
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);
}
}
模拟的请求和处理类:
package JavaWebFilter;
public class Request {
String requestStr;
public String getRequestStr() {
return requestStr;
}
public void setRequestStr(String requestStr) {
this.requestStr = requestStr;
}
}
package JavaWebFilter;
public class Response {
String responseStr;
public String getResponseStr() {
return responseStr;
}
public void setResponseStr(String responseStr) {
this.responseStr = responseStr;
}
}
package JavaWebFilter;
public class Main {
/**
* @param args
*/
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 SesitiveFilter())
;
fc.doFilter(request, response, fc);
System.out.println(request.getRequestStr());
System.out.println(response.getResponseStr());
}
}
程序运行结果:
注意最后的调用过程。
总结:我们将具体Filter实例加进FilterChian以后,调用FilterChian的doFilter方法,此时会调用具体事例的doFilter方法,具体Filter处理完并在处理的方法内部继续调用Chain中的doFilter去找到下一个filter进行处理,这样就形成filter的链条,一节传到下一节。然后返回的时候会按照的调用的顺序递归返回回去。以此形成Request和Response的过程。