宣城市网站建设_网站建设公司_在线客服_seo优化
2025/12/17 5:05:21 网站建设 项目流程

目录

一、核心基础:AntPathMatcher 规则与核心 API

1. 核心匹配规则(必记)

2. Spring Boot 中获取 AntPathMatcher 实例

3. 核心 API(过滤器场景高频使用)

二、核心实战:Spring Boot 过滤器中用 AntPathMatcher 拦截请求路径

前置知识:Spring Boot 注册过滤器的两种方式

场景 1:基础过滤器(拦截指定路径,放行排除路径)

步骤 1:编写过滤器(核心:AntPathMatcher 匹配路径)

步骤 2:启动类开启 Servlet 组件扫描

场景 2:通用路径匹配过滤器(可配置,复用性高)

步骤 1:配置文件(application.yml)定义路径规则

步骤 2:编写通用过滤器(注入配置 + AntPathMatcher)

步骤 3:通过 FilterRegistrationBean 注册过滤器(指定优先级)

三、Spring Boot 中 AntPathMatcher 高级配置

1. 自定义匹配规则

2. 与 Spring MVC 结合(路径变量提取)

3. 与 Spring Security 结合(权限路径匹配)

四、常见问题与避坑指南

1. 路径匹配过宽 / 过窄

2. 末尾斜杠导致匹配失败

3. 大小写敏感问题

4. 过滤器注册优先级问题

5. 与 PathPattern 混用(Spring Boot 5.3+)

五、总结


AntPathMatcher是 Spring 核心的路径匹配工具,在 Spring Boot 中被深度集成,尤其在过滤器 / 拦截器拦截请求路径、Spring MVC 路由、Spring Security 权限控制等场景中是核心依赖。本文从基础规则、核心 API、过滤器实战、高级用法到避坑指南,全面讲解其在 Spring Boot 中的应用,重点聚焦「过滤器拦截请求路径」场景。

一、核心基础:AntPathMatcher 规则与核心 API

1. 核心匹配规则(必记)

AntPathMatcher 基于 Ant 风格通配符,是路径匹配的核心,Spring Boot 中所有路径匹配场景(过滤器、拦截器、Security)均遵循此规则:

通配符含义示例匹配 / 不匹配
?匹配单个任意字符(不含//user/?匹配:/user/1/user/a;不匹配:/user/12/user/a/b
*匹配任意多个字符(不含//user/*匹配:/user/123/user/abc;不匹配:/user/12/34
**匹配任意多层路径(含//user/**匹配:/user/1/user/1/2/3/user/a/b;不匹配:无(除非限定前缀)
{变量名[:正则]}路径变量(Spring 扩展)/user/{id:\d+}匹配:/user/123(提取 id=123);不匹配:/user/abc
无通配符精确匹配/user/list仅匹配:/user/list;不匹配:/user/list/1/user/list2

2. Spring Boot 中获取 AntPathMatcher 实例

Spring Boot 自动配置了AntPathMatcher单例,可直接注入或通过静态方法获取:

java

运行

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.AntPathMatcher; import org.springframework.web.bind.annotation.RestController; @RestController public class DemoController { // 方式1:直接注入(推荐,Spring 容器管理) @Autowired private AntPathMatcher antPathMatcher; // 方式2:静态获取(手动创建,适用于非 Spring 管理的类) private static final AntPathMatcher MATCHER = new AntPathMatcher(); }

3. 核心 API(过滤器场景高频使用)

方法作用示例
match(String pattern, String path)判断路径是否匹配表达式matcher.match("/user/**", "/user/1/2")true
matchStart(String pattern, String path)判断路径是否匹配表达式前缀matcher.matchStart("/user/*", "/user/1/2")true
extractUriTemplateVariables(String pattern, String path)提取路径变量matcher.extractUriTemplateVariables("/user/{id}", "/user/123"){id:123}
combine(String pattern1, String pattern2)拼接路径表达式matcher.combine("/user/{id}", "order/{oid}")/user/{id}/order/{oid}

二、核心实战:Spring Boot 过滤器中用 AntPathMatcher 拦截请求路径

在 Spring Boot 中,过滤器(Filter)用于全局拦截 HTTP 请求,而AntPathMatcher是实现「按路径规则拦截 / 放行」的核心工具。以下分「基础过滤器」「通用路径匹配过滤器」两个场景讲解,覆盖 90% 实际开发需求。

前置知识:Spring Boot 注册过滤器的两种方式

Spring Boot 中注册 Filter 有两种核心方式,均支持结合 AntPathMatcher 使用:

  1. 方式 1:通过@WebFilter + @ServletComponentScan(简单,适合单个过滤器);
  2. 方式 2:通过@Bean注册FilterRegistrationBean(灵活,支持排序、路径优先级)。

场景 1:基础过滤器(拦截指定路径,放行排除路径)

需求:实现一个日志过滤器,拦截所有/api/**路径的请求,放行/api/public/**/api/login路径。

步骤 1:编写过滤器(核心:AntPathMatcher 匹配路径)

java

运行

import org.springframework.stereotype.Component; import org.springframework.util.AntPathMatcher; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import java.io.IOException; // 方式1:@WebFilter 注册(需配合启动类 @ServletComponentScan) @WebFilter(filterName = "LogFilter", urlPatterns = "/*") // 先拦截所有路径,再内部匹配 @Component public class LogFilter implements Filter { // 初始化 AntPathMatcher(Spring 容器外可手动 new,容器内建议注入) private final AntPathMatcher pathMatcher = new AntPathMatcher(); // 定义需要拦截的路径表达式 private static final String[] INCLUDE_PATTERNS = {"/api/**"}; // 定义需要放行的路径表达式 private static final String[] EXCLUDE_PATTERNS = {"/api/public/**", "/api/login"}; @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; String requestURI = httpRequest.getRequestURI(); // 获取请求路径(如 /api/user/123) // 1. 判断是否需要拦截:匹配 INCLUDE 且不匹配 EXCLUDE boolean needIntercept = false; // 检查是否在拦截列表中 for (String includePattern : INCLUDE_PATTERNS) { if (pathMatcher.match(includePattern, requestURI)) { needIntercept = true; break; } } // 检查是否在放行列表中(放行优先级更高) for (String excludePattern : EXCLUDE_PATTERNS) { if (pathMatcher.match(excludePattern, requestURI)) { needIntercept = false; break; } } // 2. 拦截逻辑:记录日志 if (needIntercept) { long startTime = System.currentTimeMillis(); System.out.println("拦截请求:" + requestURI + ",方法:" + httpRequest.getMethod()); // 执行后续过滤器/控制器 chain.doFilter(request, response); long costTime = System.currentTimeMillis() - startTime; System.out.println("请求完成:" + requestURI + ",耗时:" + costTime + "ms"); } else { // 放行:直接执行后续逻辑 chain.doFilter(request, response); } } }
步骤 2:启动类开启 Servlet 组件扫描

java

运行

import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.ServletComponentScan; @SpringBootApplication @ServletComponentScan // 扫描 @WebFilter/@WebServlet 等注解 public class BootAntPathApplication { public static void main(String[] args) { SpringApplication.run(BootAntPathApplication.class, args); } }

场景 2:通用路径匹配过滤器(可配置,复用性高)

需求:封装一个通用的路径匹配过滤器,支持通过配置文件自定义「拦截 / 放行路径」,适用于鉴权、限流等通用场景。

步骤 1:配置文件(application.yml)定义路径规则

yaml

# 自定义过滤器配置 filter: auth: include-patterns: ["/api/**", "/admin/**"] # 需要拦截的路径 exclude-patterns: ["/api/public/**", "/admin/login", "/error"] # 放行的路径
步骤 2:编写通用过滤器(注入配置 + AntPathMatcher)

java

运行

import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.util.AntPathMatcher; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.Arrays; import java.util.List; @Component public class AuthFilter implements Filter { // 注入 AntPathMatcher(Spring Boot 自动配置的单例) private final AntPathMatcher antPathMatcher; // 从配置文件注入拦截/放行路径 @Value("${filter.auth.include-patterns}") private List<String> includePatterns; @Value("${filter.auth.exclude-patterns}") private List<String> excludePatterns; // 构造器注入 AntPathMatcher(推荐,依赖注入更规范) public AuthFilter(AntPathMatcher antPathMatcher) { this.antPathMatcher = antPathMatcher; } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; String requestURI = httpRequest.getRequestURI(); // 通用路径匹配方法:判断是否需要拦截 if (isNeedIntercept(requestURI)) { // 鉴权逻辑示例:检查 Token String token = httpRequest.getHeader("Token"); if (token == null || !token.equals("valid-token")) { response.setContentType("application/json;charset=UTF-8"); response.getWriter().write("{\"code\":401,\"msg\":\"未授权\"}"); return; } } // 放行 chain.doFilter(request, response); } /** * 通用路径匹配逻辑:匹配拦截列表 && 不匹配放行列表 */ private boolean isNeedIntercept(String requestURI) { // 1. 是否匹配拦截路径 boolean matchInclude = includePatterns.stream() .anyMatch(pattern -> antPathMatcher.match(pattern, requestURI)); if (!matchInclude) { return false; } // 2. 是否匹配放行路径(放行优先级更高) boolean matchExclude = excludePatterns.stream() .anyMatch(pattern -> antPathMatcher.match(pattern, requestURI)); return !matchExclude; } }
步骤 3:通过 FilterRegistrationBean 注册过滤器(指定优先级)

java

运行

import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.util.AntPathMatcher; @Configuration public class FilterConfig { // 注册 AuthFilter,指定拦截路径(/* 表示所有路径,内部通过 AntPathMatcher 细粒度匹配) @Bean public FilterRegistrationBean<AuthFilter> authFilterRegistration(AuthFilter authFilter) { FilterRegistrationBean<AuthFilter> registration = new FilterRegistrationBean<>(); registration.setFilter(authFilter); registration.addUrlPatterns("/*"); // 先拦截所有,内部匹配 registration.setOrder(1); // 优先级(数字越小,执行越早) registration.setName("authFilter"); return registration; } // 手动注册 AntPathMatcher 单例(Spring Boot 已默认注册,可省略) @Bean public AntPathMatcher antPathMatcher() { AntPathMatcher matcher = new AntPathMatcher(); // 自定义配置:忽略路径末尾斜杠(如 /user 和 /user/ 视为同一路径) matcher.setUseTrailingSlashMatch(true); // 自定义配置:关闭大小写敏感(如 /User 和 /user 视为同一路径) matcher.setCaseSensitive(false); return matcher; } }

三、Spring Boot 中 AntPathMatcher 高级配置

1. 自定义匹配规则

通过AntPathMatcher的 setter 方法自定义匹配行为,适用于特殊场景:

java

运行

@Bean public AntPathMatcher antPathMatcher() { AntPathMatcher matcher = new AntPathMatcher(); // 1. 忽略末尾斜杠(默认 true):/user ≈ /user/ matcher.setUseTrailingSlashMatch(true); // 2. 关闭大小写敏感(默认 false):/User ≈ /user matcher.setCaseSensitive(false); // 3. 关闭后缀匹配(默认 true):/user 不匹配 /user.html matcher.setUseSuffixPatternMatch(false); // 4. 自定义路径分隔符(默认 /):适用于 Windows 路径(如 \user\123) matcher.setPathSeparator("\\"); return matcher; }

2. 与 Spring MVC 结合(路径变量提取)

在 Spring Boot Controller 中,AntPathMatcher 自动用于路径变量提取,结合过滤器可实现「路径变量校验」:

java

运行

import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/api/user") public class UserController { // 路径表达式:/api/user/{id:\d+}(仅匹配数字 id) @GetMapping("/{id:\\d+}") public String getUser(@PathVariable Long id) { return "用户ID:" + id; } }

过滤器中可提取路径变量:

java

运行

// 在过滤器中提取路径变量 String requestURI = "/api/user/123"; String pattern = "/api/user/{id:\\d+}"; Map<String, String> variables = antPathMatcher.extractUriTemplateVariables(pattern, requestURI); Long userId = Long.parseLong(variables.get("id")); // 123

3. 与 Spring Security 结合(权限路径匹配)

Spring Security 的antMatchers()底层基于AntPathMatcher,与过滤器规则一致:

java

运行

import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.web.SecurityFilterChain; @Configuration public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth // 放行 /api/public/** 路径(Ant 规则) .antMatchers("/api/public/**").permitAll() // /admin/** 路径需要 ADMIN 角色(Ant 规则) .antMatchers("/admin/**").hasRole("ADMIN") // /api/user/{id:\d+} 路径需要 USER 角色(带正则的 Ant 规则) .antMatchers("/api/user/{id:\\d+}").hasRole("USER") // 其他路径需认证 .anyRequest().authenticated() ); return http.build(); } }

四、常见问题与避坑指南

1. 路径匹配过宽 / 过窄

  • 问题:使用/**会匹配所有路径,容易误拦截静态资源(如/css/**/js/**);
  • 解决:细化拦截规则,如/api/**而非/**,并在放行列表中添加静态资源路径(/static/**/css/**)。

2. 末尾斜杠导致匹配失败

  • 问题:/user/user/被判定为不同路径;
  • 解决:设置matcher.setUseTrailingSlashMatch(true)(默认开启),或统一请求路径格式。

3. 大小写敏感问题

  • 问题:Windows 系统下/User/user实际是同一路径,但 AntPathMatcher 默认区分大小写;
  • 解决:设置matcher.setCaseSensitive(false)关闭大小写敏感。

4. 过滤器注册优先级问题

  • 问题:多个过滤器执行顺序混乱,导致鉴权过滤器在日志过滤器之后执行;
  • 解决:通过FilterRegistrationBean.setOrder()指定优先级(数字越小,执行越早)。

5. 与 PathPattern 混用(Spring Boot 5.3+)

  • 问题:Spring Boot 5.3+ 推荐使用PathPattern替代AntPathMatcher,两者规则略有差异;
  • 解决:
    1. 如需兼容旧代码,继续使用AntPathMatcher
    2. 新项目可切换到PathPattern,通过PathPatternParser实现路径匹配:

      java

      运行

      import org.springframework.web.util.pattern.PathPattern; import org.springframework.web.util.pattern.PathPatternParser; // PathPattern 示例 PathPatternParser parser = new PathPatternParser(); PathPattern pattern = parser.parse("/api/**"); boolean match = pattern.matches(PathContainer.parsePath("/api/user/123")); // true

五、总结

在 Spring Boot 中,AntPathMatcher是「路径精细化控制」的核心工具,尤其在过滤器拦截请求路径场景中,通过 Ant 风格通配符可灵活实现「拦截 / 放行」规则:

  1. 核心用法:过滤器中先拦截所有路径(/*),再通过match()方法结合 Ant 规则细粒度匹配;
  2. 最佳实践
    • 配置文件定义拦截 / 放行路径,提高可维护性;
    • 通过FilterRegistrationBean注册过滤器,指定执行优先级;
    • 自定义AntPathMatcher规则适配业务场景(如忽略大小写、末尾斜杠);
  3. 避坑点:避免路径匹配过宽、注意大小写 / 末尾斜杠、明确过滤器执行顺序。

掌握AntPathMatcher能让 Spring Boot 过滤器、拦截器、Security 权限控制的路径规则更灵活,是后端开发必备的核心技能。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询