shiro学习16-shiro提供的filter-OncePerRequestFilter

从这一节开始我们介绍shiro提供的filter,记住尽管这是shiro提供的,但是不一定适合你的项目,我们看他们源码的目的是理解其中的运行逻辑,在开发中不一定强制要求使用他们提供的filter。

我们从OnecPerRequestFilter,虽然这个类不是一个最顶层的类,他还有父类NameableFilter,但是NameableFilter我在开发中没有使用它提供的名字的便利性,而是根据在spring中配置的benaName决定filter的名字,所以直接跳过NameableFilter。OnecPerRequestFilter这个类是所有的其他的filter的父类,所有的filter的doFilter方法都是调用的这个类中的doFIlter方法,所以必须好好看这个类的doFilter方法,

 

public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        String alreadyFilteredAttributeName = getAlreadyFilteredAttributeName();//获得名字防止多次执行,
        if ( request.getAttribute(alreadyFilteredAttributeName) != null ) {//防止多次执行,防止错误配置
            log.trace("Filter '{}' already executed.  Proceeding without invoking this filter.", getName());
            filterChain.doFilter(request, response);//如果当前的filter已经执行过则直接放行不再重复执行。
        } else //noinspection deprecation
            if (/* added in 1.2: */ !isEnabled(request, response) ||
                /* retain backwards compatibility: */ shouldNotFilter(request) ) {//根据enabled判断是否要执行这个filter,如果不执行,则直接放行
            log.debug("Filter '{}' is not enabled for the current request.  Proceeding without invoking this filter.",
                    getName());
            filterChain.doFilter(request, response);
        } else {
            // Do invoke this filter...
            log.trace("Filter '{}' not yet executed.  Executing now.", getName());
            request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE);//在执行前放入一个值,作为标记,和上面的配合使用。防止重复执行
 
            try {
 
                doFilterInternal(request, response, filterChain);//执行doFilterInternal方法,所以实现类只要复写这个方法即可,这个方法才是这个filter里面真正要实现的业务逻辑。  
         } finally {
                // Once the request has finished, we're done and we don't
                // need to mark as 'already filtered' any more.
                request.removeAttribute(alreadyFilteredAttributeName);
            }
        }
}

  

从源码中可以看出,我们自己的业务逻辑要在doFilterInternal这个方法中实现,所以实现类只要实现这个方法即可,在这个类中这个方法也是一个抽象方法。

 

 

相关推荐