将配置的拦截器链加入到FilterChain中

我们可能会在shiro中配置上图这样的拦截器链,但是像Tomcat这样的服务器中的Filter都是需要配置在web.xml中才会生效。而在上篇文章中,我们在web.xml中只配置了一个Filter,所以Shiro需要做的就是把配置的拦截器链“嫁接”到服务器原来的Filter链中。
在上篇中,我们提到,最后发挥拦截功能的是SpringShiroFilter这个拦截器,所以也从它开始分析
SpringShiroFilter的继承体系
其中OncePerRequestFilter对Filter接口的doFilter方法进行了重载:
//从类的名字可以看出,该Filter对一次请求只会应用一次拦截
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);
} else //noinspection deprecation
if (/* added in 1.2: */ !isEnabled(request, response) || //isEnabled方法默认返回true,shouldNotFilter默认返回false
/* retain backwards compatibility: */ shouldNotFilter(request) ) {
log.debug("Filter '{}' is not enabled for the current request. Proceeding without invoking this filter.",
getName());
filterChain.doFilter(request, response);
} else {
//将当前Filter的name添加到Request的属性中,在上面第一、二行代码中可以看到,如果请求再次遇到该Filter不会出现二次拦截
request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE);
try {