大家都知道JavaEE中的Filter是用了责任链模式来实现的,请求值先到达Filter,根据Filter在web.xml的配置顺序一个个按顺序地处理,处理完以后,再按反顺序来处理响应信息,有点像是一个栈(先处理请求的Filter,后处理响应)。下面就山寨一下它的实现,来说明它的实现原理。
package myself.filter;
/**
* 请求
* @author zyb
* @since 2012-12-1
*
*/
public class Request {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
package myself.filter;
/**
* 响应
*
* @author zyb
* @since 2012-12-1
*
*/
public class Response {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
package myself.filter;
/**
* 过滤器接口
* @author zyb
* @since 2012-12-1
*
*/
public interface Filter {
/**
* 处理请求和响应
* @param request 请求
* @param response 响应
* @param chain 过滤器链
*/
void doFilter(Request request, Response response, FilterChain chain);
}
package myself.filter;
import java.util.ArrayList;
import java.util.List;
/**
* 过滤器链
* @author zyb
* @since 2012-12-1
*
*/
public class FilterChain implements Filter { // 在JavaEE的FilterChain源码中并没有实现Filter接口
// 用于保存所有要处理的过滤器
private List<Filter> filters = new ArrayList<Filter>();
// 索引,用于记数
private int index = 0;
@Override
public void doFilter(Request request, Response response, FilterChain chain) {
// 如果所有的过滤器都已经处理完
if (index == filters.size()) {
return;
}
// 取出相应的过滤器
Filter filter = filters.get(index);
// 索引加1
index++;
// 调用具体的过滤器处理请求和响应
filter.doFilter(request, response, chain);
}
// 往过滤器链中添加过滤器
public void addFilter(Filter filter) {
this.filters.add(filter);
}
}
package myself.filter;
/**
* 客户端程序
* @author zyb
* @since 2012-12-1
*
*/
public class Client {
public static void main(String[] args) {
Request request = new Request();
request.setValue("abcd");
Response response = new Response();
FilterChain filter = new FilterChain();
// 将请求值变成大写字母
filter.addFilter(new Filter() {
@Override
public void doFilter(Request request, Response response, FilterChain chain) {
System.out.println("第一个Filter处理...请求值:" + request.getValue());
StringBuilder sb = new StringBuilder();
for (int i = 0; i < request.getValue().length(); i++) {
sb.append((char) (request.getValue().charAt(i) - 32));
}
Response result = new Response();
result.setValue(sb.toString());
chain.doFilter(request, response, chain);
System.out.println("第一个Filter响应...响应值:" + result.getValue());
}
});
// 将请求值加1
filter.addFilter(new Filter() {
@Override
public void doFilter(Request request, Response response, FilterChain chain) {
System.out.println("第二个Filter处理...请求值:" + request.getValue());
StringBuilder sb = new StringBuilder();
for (int i = 0; i < request.getValue().length(); i++) {
sb.append((char) (request.getValue().charAt(i) + 1));
}
Response result = new Response();
result.setValue(sb.toString());
chain.doFilter(request, response, chain);
System.out.println("第二个Filter响应...响应值:" + result.getValue());
}
});
filter.doFilter(request, response, filter);
}
}
打印信息:
第一个Filter处理...请求值:abcd
第二个Filter处理...请求值:abcd
第二个Filter响应...响应值:bcde
第一个Filter响应...响应值:ABCD
打印的信息跟前面说的是一致的,先进后出。。呵