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