专业编程基础技术教程

网站首页 > 基础教程 正文

责任链的实现:Servlet Filter(责任链模式应用)

ccvgpt 2024-07-30 20:52:26 基础教程 57 ℃

责任链模式定义

一个请求有多个对象来处理,这些对象构成一条链,但具体由哪个对象来处理,根据条件判断来确定,如果不能处理会传递给该链中的下一个对象,直到有对象处理它为止。

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);
    }
}

调用时序图

过程说明:

责任链的实现:Servlet Filter(责任链模式应用)

客户端Client先调用了 ApplicationFilterChain 的 doFilter 方法,FilterChain 通过调用 internalDoFilter() 方法来串连所有的过滤处理器。

首先,调用其管理的过滤器集合中的第一个过滤器 XXFilter(以上图为例),并将自己传递给对应的过滤器。

XXFilter 过滤器执行了 doFilter 方法中的逻辑后,又会调回到 FilterChain 中,继续调用 doFilter 方法和 internalDoFilter 方法来执行接下去的过滤器。

当过滤器都执行完成后,FilterChain会调用 Servlet 中的 service() 方法去执行真正的 Servlet 请求。

执行完成后,会通过客户端一开始就传递到链中的 HttpServletResponse 中的 ServletOutputStream 对象,将响应的数据返回给客户端来完成本次的处理。

Tags:

最近发表
标签列表