责任链模式定义
一个请求有多个对象来处理,这些对象构成一条链,但具体由哪个对象来处理,根据条件判断来确定,如果不能处理会传递给该链中的下一个对象,直到有对象处理它为止。
servlet Filter的实现
首先看抽象处理接口FilterChain
public interface FilterChain {
void doFilter(ServletRequest request, ServletResponse response);
}
ApplicationFilterChain对FilterChain的实现
public final class ApplicationFilterChain implements FilterChain {
/**
* 当前filter的索引位置
*/
private int pos = 0;
/**
* filter的数量
*/
private int n = 0;
@Override
public void doFilter(ServletRequest request, ServletResponse response){
internalDoFilter(request,response);
}
private void internalDoFilter(ServletRequest request,
ServletResponse response) {
// Call the next filter if there is one
if (pos < n) {
ApplicationFilterConfig filterConfig = filters[pos++];
try {
Filter filter = filterConfig.getFilter();
filter.doFilter(request, response, this);
} catch (IOException | ServletException | RuntimeException e) {
throw e;
}
return;
}
// 过滤器已处理完毕
try {
servlet.service(request, response);
} catch (IOException | ServletException | RuntimeException e) {
throw e;
}
}
}
Filter接口
public interface Filter {
void doFilter(ServletRequest request, ServletResponse response, FilterChain chain);
}
Filter的一个具体实现
public class XXFilter implement Filter{
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
if (!(request instanceof HttpServletRequest)) {
throw new ServletException(request + " not HttpServletRequest");
}
if (!(response instanceof HttpServletResponse)) {
throw new ServletException(request + " not HttpServletResponse");
}
doFilter((HttpServletRequest) request, (HttpServletResponse) response, chain);
}
protected void doFilter(HttpServletRequest request, HttpServletResponse response,
FilterChain chain) {
chain.doFilter(request, response);
}
}
调用时序图
过程说明:
客户端Client先调用了 ApplicationFilterChain 的 doFilter 方法,FilterChain 通过调用 internalDoFilter() 方法来串连所有的过滤处理器。
首先,调用其管理的过滤器集合中的第一个过滤器 XXFilter(以上图为例),并将自己传递给对应的过滤器。
XXFilter 过滤器执行了 doFilter 方法中的逻辑后,又会调回到 FilterChain 中,继续调用 doFilter 方法和 internalDoFilter 方法来执行接下去的过滤器。
当过滤器都执行完成后,FilterChain会调用 Servlet 中的 service() 方法去执行真正的 Servlet 请求。
执行完成后,会通过客户端一开始就传递到链中的 HttpServletResponse 中的 ServletOutputStream 对象,将响应的数据返回给客户端来完成本次的处理。