【问题标题】:Spring MVC picks the wrong controller methodSpring MVC 选择了错误的控制器方法
【发布时间】:2013-05-15 13:52:00
【问题描述】:

在我的应用程序中,我遇到了一种情况,即 spring mvc 始终选择错误的控制器方法来执行。下面spring的调试日志显示了问题,它找到了两个匹配项,一个用于我的通用处理所有非手动映射控制器,它映射到/api/**,一个用于我正在寻找的实际东西api/companies/2/records/cabinets/FileTypes/50/1 spring mvc 然后选择@987654323 @handler 覆盖它找到的更具体的处理程序。

我对spring的理解是,如果一个请求映射有两个匹配,那么spring会选择url较长的handle方法。为什么 spring mvc 选择较短的映射?

给定以下映射:

  • /api/companies/{id}/records/cabinets/FileTypes/{fileTypeId}/{versionId} 映射到方法1
  • /api/** 映射到方法2

以及路径api/companies/2/records/cabinets/FileTypes/50/1 spring mvc 应该选择什么作为上述两个 url 的处理程序方法。

这里是调试日志中的相关行。

17:58:49,858 DEBUG [DispatcherServlet] DispatcherServlet with name 'main' processing PUT request for [/web/api/companies/2/records/cabinets/FileTypes/50/1]
17:58:49,858 TRACE [DispatcherServlet] Testing handler map [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping@2b25f2be] in DispatcherServlet with name 'main'
7:58:49,858 DEBUG [RequestMappingHandlerMapping] Looking up handler method for path /api/companies/2/records/cabinets/FileTypes/50/1
17:58:49,859 TRACE [RequestMappingHandlerMapping] Found 2 matching mapping(s) for [/api/companies/2/records/cabinets/FileTypes/50/1] : [{[/api/**],methods=[PUT],params=[],headers=[],consumes=[],produces=[],custom=[]}, {[/api/companies/{id}/records/cabinets/FileTypes/{fileTypeId}/{versionId}],methods=[PUT],params=[],headers=[],consumes=[],produces=[],custom=[]}]

【问题讨论】:

  • 你是如何尝试这个的?我使用 `@RequestMapping(value="[mapping]") 测试了四种不同的映射,每个映射都按预期工作。我使用了'something/**'、'something/*'、'something/'和'something/else',并且每个都按预期工作(使用'something/more specific'、'something/specific'、'something/ ' 和 'something/else')。

标签: spring spring-mvc


【解决方案1】:

我能够复制您所看到的行为。所以你的行为有两个映射:

/api/companies/{id}/records/cabinets/FileTypes/{fileTypeId}/{versionId}

/api/**

/api/companies/2/records/cabinets/FileTypes/50/1 的请求与第二条路径匹配。

我尝试了一些不同的路径:

/api/companies/{id}/records/cabinets/FileTypes

/api/**

/api/companies/2/records/cabinets/FileTypes 提出请求,这一次大约是第一个匹配!

我认为这是一个错误,我建议在 Spring JIRA 网站上提交工单。

【讨论】:

    【解决方案2】:

    这确实是一个错误(参见herehere)。

    我相信映射考虑了第一个表达式中括号的数量:

    /api/companies/{id}/records/cabinets/FileTypes/{fileTypeId}/{versionId}
                   ^--                             ^--          ^--
    

    由于第一个中包含三个括号(模式),而第二个中只有一个模式 (**),因此认为第一个更通用。

    解决方法:

    由于*/* 的计算方式相同,请尝试创建第二个表达式,而不是/api/**,例如:

    /api/**/**/**/**
    

    这有四种模式,因此使其比另一种“更通用”。但实际上,它相当于/api/**。这将使它最后评估。

    由于存在这种有点“简单”的解决方法,因此我相信该错误将需要很长时间才能得到纠正,如果可以的话。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-05-09
      • 2012-01-11
      • 1970-01-01
      • 2018-04-07
      • 2016-11-06
      • 1970-01-01
      • 2015-09-12
      相关资源
      最近更新 更多