AntPathMatcher 一个路径匹配工具类(Filter的使用伙伴)
摘要:项目中经常需要使用到对指定的接口访问路径进行一系列的操作,这时候我们就需要使用路径匹配,推荐使用Spring
框架或者apache
提供的路径匹配工具类,简化我们的代码。
背景
- 为什么需要单独开一篇文章来说这个工具类??
因为项目中经常需要使用
Filter
来过滤指定的路径,又想保持和Shiro
或者Security
框架一致的过滤规则,所以再此记录一下简单的使用案例。
案例
通过下面的单元测试案例就能知道过滤规则生效的方式,后面给出我项目中是如何使用的。
单元测试
代码
@Test
public void testMatch(){
// 完全相等才匹配,结果为true
this.matchAndPrint("/","/");
// 完全相等才匹配,结果为false
this.matchAndPrint("/","/index");
// 匹配/welcome/开头的所有路由,结果为false
this.matchAndPrint("/welcome/**","/index");
// 匹配/welcome开头的所有路由,结果为true
this.matchAndPrint("/welcome/**","/welcome");
// 匹配/welcome开头的所有路由,结果为false
this.matchAndPrint("/welcome/**","/welcome111");
// 匹配/welcome/开头的所有路由,结果为true
this.matchAndPrint("/welcome/**","/welcome/");
// 匹配/welcome/开头的所有路由,结果为true
this.matchAndPrint("/welcome/**","/welcome/index");
// 匹配/user/**/detail,中间的**是任意路径,结果为true
this.matchAndPrint("/user/**/detail","/user/1/detail");
// 匹配/user/**/detail,中间的**是任意路径,结果为true
this.matchAndPrint("/user/**/detail","/user/detail");
}
private void matchAndPrint(String pattern, String path){
AntPathMatcher antPathMatcher = new AntPathMatcher();
boolean match = antPathMatcher.match(pattern, path);
System.out.println("匹配规则="+pattern+",匹配路径="+path+",匹配结果=" + match);
}
结果
匹配规则=/,匹配路径=/,匹配结果=true
匹配规则=/,匹配路径=/index,匹配结果=false
匹配规则=/welcome/**,匹配路径=/index,匹配结果=false
匹配规则=/welcome/**,匹配路径=/welcome,匹配结果=true
匹配规则=/welcome/**,匹配路径=/welcome111,匹配结果=false
匹配规则=/welcome/**,匹配路径=/welcome/,匹配结果=true
匹配规则=/welcome/**,匹配路径=/welcome/index,匹配结果=true
匹配规则=/user/**/detail,匹配路径=/user/1/detail,匹配结果=true
匹配规则=/user/**/detail,匹配路径=/user/detail,匹配结果=true
项目中的使用方式
代码
GatewayFilter
@Slf4j
public class GatewayFilter implements Filter {
/** 不需要权限的URL */
private static final List<String> ANNO_URLS = new ArrayList<>();
static {
ANNO_URLS.add("/");
ANNO_URLS.add("/index");
ANNO_URLS.add("/open-api/**");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest)request;
// 如果需要权限则
if(!this.matchAnno(httpServletRequest.getRequestURI())){
log.info(httpServletRequest.getRequestURI() + "访问路径没有在开放列表中");
}
chain.doFilter(request, response);
}
/**
* 匹配是否需要权限
* @param uri
* @return
*/
private boolean matchAnno(String uri){
return ANNO_URLS.stream().anyMatch(annoUrl -> {
AntPathMatcher antPathMatcher = new AntPathMatcher();
return antPathMatcher.match(annoUrl, uri);
});
}
}
GatewayFilterConfig
@Configuration
public class GatewayFilterConfig {
@Bean
public FilterRegistrationBean<GatewayFilter> gatewayFilter() {
FilterRegistrationBean<GatewayFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new GatewayFilter());
// 需要拦截的路径/*是所有
registrationBean.addUrlPatterns("/*");
// 设置顺序,数值小的先执行
registrationBean.setOrder(1);
return registrationBean;
}
}
转载自:https://juejin.cn/post/7368784048574414882