likes
comments
collection
share

AntPathMatcher 一个路径匹配工具类(Filter的使用伙伴)

作者站长头像
站长
· 阅读数 24

摘要:项目中经常需要使用到对指定的接口访问路径进行一系列的操作,这时候我们就需要使用路径匹配,推荐使用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
评论
请登录