6

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

我对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=[]}]
4

2 回答 2

7

这确实是一个错误(请参见此处此处)。

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

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

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

解决方法:

As*/*以相同的方式计算,尝试制作第二个表达式,而不是/api/**,例如:

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

这有四种模式,因此使其比另一种“更通用”。但在实践中,它等价于/api/**. 这将使它最后评估。

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

于 2013-05-21T02:50:51.027 回答
3

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

./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 网站上提交一张票。

于 2013-05-21T01:11:32.750 回答