You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot REST端点匹配异常求助:带format参数仍匹配无format端点

Spring MVC路由匹配问题排查与解决

问题根源

  1. 路径变量贪婪匹配:第二个端点的路径/record/{id}/{lcId}采用默认路径变量规则,会贪婪匹配路径末尾的所有内容,包括带点的字符串(比如2.json会被解析为lcId的值),导致带format的URL也能匹配到第二个端点。
  2. Headers匹配优先级干扰:第二个端点指定了Accept头的匹配条件,当请求的Accept头符合该条件时,Spring会认为该端点的匹配度更高,进一步覆盖了路径的具体性优先级。

解决方案

方案一:约束第二个端点的路径变量格式

通过正则表达式限制lcId路径变量不能包含点,从根源上避免路径匹配歧义。修改第二个端点的路径定义:

@GetMapping(value = "/record/{id}/{lcId:[^.]+}", // 用正则约束lcId不含点
            headers = {ACCEPT_HEADER_JSON, 
                       ACCEPT_HEADER_APPLICATION_RDF_XML, 
                       ACCEPT_HEADER_RDF_XML,                        
                       ACCEPT_HEADER_APPLICATION_XML},
            produces = {MediaType.APPLICATION_JSON_VALUE,                        
                        MediaType.TEXT_XML_VALUE,
                        MediaType.APPLICATION_XML_VALUE, 
                        HttpHeaders.CONTENT_TYPE_APPLICATION_RDF_XML, 
                        HttpHeaders.CONTENT_TYPE_RDF_XML})
public ResponseEntity<String> getwithHeader(
            @PathVariable (value = "id") String id,
            @PathVariable (value = "lcId")String lcId,
            HttpServletRequest request) throws IOException {
        ...
}

[^.]+表示匹配任意不含点的字符,这样带点的URL(如/record/1/2.json)只会匹配第一个端点,不带点的URL(如/record/1/2)则匹配第二个端点。

方案二:提升第一个端点的匹配优先级

如果不想修改路径规则,可以给第一个端点添加与第二个端点一致的headers条件,确保当路径和Headers都匹配时,更具体的路径端点优先:

@GetMapping(value = "/record/{id}/{lcId}.{format}",
            headers = {ACCEPT_HEADER_JSON, 
                       ACCEPT_HEADER_APPLICATION_RDF_XML, 
                       ACCEPT_HEADER_RDF_XML,                        
                       ACCEPT_HEADER_APPLICATION_XML},
            produces = {MediaType.APPLICATION_JSON_VALUE, 
                        MediaType.TEXT_XML_VALUE,
                        MediaType.APPLICATION_XML_VALUE,                                                                         
                        HttpHeaders.CONTENT_TYPE_APPLICATION_RDF_XML, 
                        HttpHeaders.CONTENT_TYPE_RDF_XML})
public ResponseEntity<String> getWithFormat(
            @PathVariable String id,
            @PathVariable String lcId,
            @PathVariable (value = "format") String format,
            HttpServletRequest request) throws IOException {

      ....
}

此时Spring会优先选择路径更具体的第一个端点,同时满足Headers匹配条件。

验证说明

  • 访问/record/1/2.json:会匹配第一个端点,format参数被正确解析为json
  • 访问/record/1/2且携带符合要求的Accept头:匹配第二个端点
  • 访问/record/1/2但Accept头不符合:会返回406 Not Acceptable,符合预期

内容的提问来源于stack exchange,提问作者Watermelon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 11:47:10