Spring Controller GetMapping正则表达式:排除特定前缀路径
解决Spring控制器路径匹配问题:排除WebSocket路径并支持多级HTTP路径
首先,我们来拆解你遇到的问题根源:
你之前尝试的正则为什么出错?
- 最初的
/{path:[^\\.]*}:这个正则只能匹配单级无后缀路径,因为[^\\.]*不匹配斜杠/,所以多级路径(比如/abc/def)会被Spring拆分为多个路径分段,无法匹配这个单变量的路径模式。 /**/{path:[^\\.]*}:/**会匹配任意多级路径(包括/websock/xxx),后面的[^\\.]*只是匹配最后一个无后缀的分段,没有任何排除WebSocket的逻辑,所以会把WebSocket请求也包含进来。- 错误的负前瞻表达式
"/**/{path:^(?!websock).*}/{path:[^\\.]*}":这里有两个致命问题:- 重复定义了
path路径变量,Spring不允许同一个方法中出现同名的路径变量; - 逻辑错误:
/**会匹配到/websock部分,后面的path变量只匹配最后一个分段(比如/websock/abc中的abc),负前瞻^(?!websock)只会检查最后一个分段,而不是整个路径,所以根本起不到排除WebSocket路径的作用,反而因为语法错误导致无法匹配任何请求。
- 重复定义了
两种可行的解决方案
方案1:使用正确的正则表达式(纯路径变量实现)
要满足排除/websock前缀、支持多级路径、排除带后缀的静态资源三个需求,我们需要编写一个能匹配含斜杠的完整路径,同时满足以下条件的正则:
- 路径不以
websock开头(对应请求路径/websock/xxx会被排除); - 路径中所有分段都不含点
.(排除静态资源如/abc.js或/abc/def.css)。
对应的Spring控制器写法:
@GetMapping(value = "/{path:^(?!websock)[^\\.]+(/[^\\.]+)*}") public String redirect(@PathVariable(value="path") String path) { LOGGER.debug("In redirect path:" + path); return "forward:/"; }
正则解析:
^(?!websock):负前瞻断言,确保路径的第一个分段不是websock;[^\\.]+:匹配第一个不含点的路径分段;(/[^\\.]+)*:匹配零个或多个后续的不含点的路径分段(支持多级路径)。
方案2:使用Spring的excludePatterns(更简洁易维护)
其实Spring MVC的@RequestMapping支持直接排除特定路径,不需要复杂的正则,这种方法更直观,出错概率更低:
@RequestMapping( value = "/**", method = RequestMethod.GET, excludePatterns = {"/websock/**", "**.*"} ) public String redirect(HttpServletRequest request) { // 如果需要获取路径,可以通过HttpServletRequest获取 String path = request.getRequestURI().substring(request.getContextPath().length()); LOGGER.debug("In redirect path:" + path); return "forward:/"; }
参数解析:
value = "/**":匹配所有GET请求路径;excludePatterns = {"/websock/**", "**.*"}:/websock/**:排除所有以/websock开头的路径;**.*:排除所有带后缀的静态资源路径(比如.js、.css、.html等)。
这个方案不需要处理复杂的正则,代码可读性更高,推荐使用。
内容的提问来源于stack exchange,提问作者plex4r
相关产品推荐
相关产品推荐

