shiro学习20-shiro提供的filter-PathMatchingFilter类

这个类也是AdviceFilter的实现类,我们先看看他的preHandle方法

protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
        if (this.appliedPaths == null || this.appliedPaths.isEmpty()) {
            if (log.isTraceEnabled()) {
                log.trace("appliedPaths property is null or empty.  This Filter will passthrough immediately.");
            }
            return true;
        }
        for (String path : this.appliedPaths.keySet()) {
            // If the path does match, then pass on to the subclass implementation for specific checks
            //(first match 'wins'):
            if (pathsMatch(path, request)) {
                log.trace("Current requestURI matches pattern '{}'.  Determining filter chain execution...", path);
                Object config = this.appliedPaths.get(path);
                return isFilterChainContinued(request, response, path, config);
            }
        }
        //no path matched, allow the request to go through:
        return true;
}

 

这个类的属性appliedPaths,表示我们shiroFilterFactoryBean的配置时配置的路径=filter[param1,param2],中路径和param的数组。在上面的方法中,如果我们没有配置任何路径则直径放行,当然这个判断一定不会发生,因为调用这个filter的前提就是已经配置了对应的路径了。这里的param可以表示任意东西,具体取决于你的代码,比如如果你决定将某个访问路径锁需要的权限写死在配置中,就可以用这个param表示权限。

 

然后再根据配置的路径和这次访问的路径,在第一个匹配的路径中,获得这个路径对应的参数,然后调用isFilterChainContinued这个方法,源代码如下:

private boolean isFilterChainContinued(ServletRequest request, ServletResponse response,
                                           String path, Object pathConfig) throws Exception {
        if (isEnabled(request, response, path, pathConfig)) { //当前filter是否可用,默认是可用的。如果不可用直接返回的是true,表示继续执行剩下的filter。
            if (log.isTraceEnabled()) {
                log.trace("Filter '{}' is enabled for the current request under path '{}' with config [{}].  " +
                        "Delegating to subclass implementation for 'onPreHandle' check.",
                        new Object[]{getName(), path, pathConfig});
            }
            //The filter is enabled for this specific request, so delegate to subclass implementations
            //so they can decide if the request should continue through the chain or not:
            return onPreHandle(request, response, pathConfig);//最终决定权在这个方法中,将配置的参数传入进去。
        }
 
        if (log.isTraceEnabled()) {
            log.trace("Filter '{}' is disabled for the current request under path '{}' with config [{}].  " +
                    "The next element in the FilterChain will be called immediately.",
                    new Object[]{getName(), path, pathConfig});
        }
        //This filter is disabled for this specific request,
        //return 'true' immediately to indicate that the filter will not process the request
        //and let the request/response to continue through the filter chain:
        return true;
    }

 

通过上面的代码我们知道最终能否执行后面的代码(包括剩余的filter和servlet)都取决于onpreHandle方法,所以继承该类的类中只要实现这个方法即可。

 

但是这个类有一个不好的地方,他在onPreHandle中使用了配置的param参数,如果我们使用这些参数的话,程序的权限配置就不够灵活了,比如我们的访问权限可能不是固定的,而是可以在运行时配置的,这样就无法通过param来传递。所以我觉得在工作中没有必要使用这些参数,再调用权限检查某个路径能否访问时从数据库(或其他存储)中查询该路径需要的权限+当前用户的权限就可以了。

但是在某些条件下,某些路径的访问权限就是固定的,那么我们就可以使用这个类的继承类,这样更加方便。

继续看它的继承类,继承类有这些:

·AccessControlFilter

·AnonymousFilter

`NoSessionCreationFilter

 

相关推荐