首页 短视频

SpringMVC 路径匹配深度解析:/* 与 /** 的终极区别

分类:短视频
字数: (6386)
阅读: (4932)
内容摘要:SpringMVC 路径匹配深度解析:/* 与 /** 的终极区别,

在 SpringMVC 的配置中,/*/** 这两种路径匹配模式经常让人感到困惑。很多开发者在使用 Spring Boot 整合 SpringMVC 时,由于对这两种模式理解不透彻,导致请求无法正确映射到 Controller 方法,最终引发 404 错误。本文将深入剖析这两种模式的底层原理、应用场景以及实战避坑经验。

问题场景重现:一次难以捉摸的 404

假设我们希望拦截所有以 /api 开头的请求,并将其转发到相应的 Controller 进行处理。我们可能会尝试使用以下配置:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("index");
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/api/*"); // 或者 "/api/**"
    }
}
public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("请求被拦截:" + request.getRequestURI());
        return true;
    }
}

如果我们使用 /api/*,并且请求的 URL 是 /api/user/123,那么请求可能无法被正确拦截。但是,如果我们将配置改为 /api/**,那么请求就能成功被拦截。这是为什么呢?

SpringMVC 路径匹配深度解析:/* 与 /** 的终极区别

底层原理深度剖析:AntPathMatcher 的秘密

SpringMVC 使用 AntPathMatcher 来进行路径匹配。AntPathMatcher 支持三种通配符:

  • ?:匹配单个字符。
  • *:匹配零个或多个字符,但不匹配路径分隔符 /
  • **:匹配零个或多个目录,包括路径分隔符 /

因此,/* 只能匹配 /api 下的一级路径,例如 /api/user/api/product,而无法匹配更深层次的路径,如 /api/user/123/** 则可以匹配 /api 下的任何深度的路径,包括 /api 本身。

SpringMVC 路径匹配深度解析:/* 与 /** 的终极区别

AntPathMatcher 采用的是贪婪匹配策略,即尽可能多地匹配字符。这意味着,如果有多个匹配的模式,它会选择最长、最具体的模式。

在实际生产环境中,我们经常使用 Nginx 作为反向代理服务器,将客户端的请求转发到 Spring Boot 应用。Nginx 的负载均衡能力可以有效提高系统的并发处理能力。同时,我们也可以使用宝塔面板等工具来简化 Nginx 的配置和管理。如果使用了 Nginx,则需要注意 Nginx 的配置和 SpringMVC 的路径匹配规则是否一致,避免出现请求被 Nginx 拦截或转发错误的情况。在高并发场景下,需要根据实际情况调整 Nginx 的 worker 进程数和最大连接数等参数,以保证系统的稳定性和性能。

SpringMVC 路径匹配深度解析:/* 与 /** 的终极区别

具体代码/配置解决方案:灵活运用 Ant 风格路径匹配

为了更好地理解和使用 /*/**,我们可以通过以下示例进行说明:

1. 使用 /* 匹配一级路径:

SpringMVC 路径匹配深度解析:/* 与 /** 的终极区别
@GetMapping("/api/*")
public String handleApiRequest(HttpServletRequest request) {
    String path = request.getRequestURI();
    System.out.println("请求路径:" + path); // 输出:/api/user 或 /api/product
    return "api";
}

2. 使用 /** 匹配多级路径:

@GetMapping("/api/**")
public String handleApiRequest(HttpServletRequest request) {
    String path = request.getRequestURI();
    System.out.println("请求路径:" + path); // 输出:/api/user/123 或 /api/product/detail
    return "api";
}

3. 结合使用 /*/**

@GetMapping({ "/api/*", "/api/**" })
public String handleApiRequest(HttpServletRequest request) {
    String path = request.getRequestURI();
    System.out.println("请求路径:" + path);
    return "api";
}

除了在 Controller 中使用 @GetMapping 等注解进行路径匹配外,我们还可以在 Spring Security 的配置中使用 /*/** 来控制资源的访问权限:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
        .antMatchers("/admin/**").hasRole("ADMIN") // 匹配 /admin 下的任何深度的路径
        .antMatchers("/user/*").hasRole("USER")   // 匹配 /user 下的一级路径
        .antMatchers("/**").permitAll();           // 允许所有用户访问其他路径
}

实战避坑经验总结:细节决定成败

  1. 仔细审查配置: 在使用 /*/** 时,务必仔细审查配置文件和代码,确保路径匹配规则符合预期。
  2. 避免过度宽泛的匹配: 尽量避免使用过于宽泛的匹配规则,例如 /**,这可能会导致不必要的请求被拦截,影响系统性能。
  3. 考虑优先级: 当存在多个匹配的模式时,SpringMVC 会选择最长、最具体的模式。因此,需要仔细考虑不同模式的优先级。
  4. 结合实际场景: 根据实际业务需求选择合适的路径匹配模式。例如,如果只需要拦截一级路径,则使用 /*;如果需要拦截多级路径,则使用 /**
  5. 注意 URL 编码: URL 中可能包含特殊字符,需要进行编码处理,避免影响路径匹配结果。

理解 SpringMVC 中 /*/** 的区别,是编写高效、稳定的 Web 应用的基础。希望本文能够帮助你更好地掌握这两种路径匹配模式,避免在实际开发中踩坑。

SpringMVC 路径匹配深度解析:/* 与 /** 的终极区别

转载请注明出处: 半杯凉茶

本文的链接地址: http://m.acea3.store/blog/092771.SHTML

本文最后 发布于2026-04-01 23:12:51,已经过了25天没有更新,若内容或图片 失效,请留言反馈

()
您可能对以下文章感兴趣
评论
  • 欧皇附体 6 天前
    关于 AntPathMatcher 匹配规则的讲解非常详细,感谢博主!
  • 绿豆汤 4 天前
    写得真好!之前一直对这个概念模棱两可,现在终于彻底明白了。