在我的应用程序中,我遇到一种情况,即spring mvc始终选择错误的控制器方法来执行。从下面的弹簧调试日志显示问题,它找到两个匹配一个用于我的通用处理所有未映射的映射控制器映射到/api/**
和一个用于我想要的实际事物api/companies/2/records/cabinets/FileTypes/50/1
spring mvc然后在它找到的更具体的处理程序上选择/api/**
处理程序。
我对spring的理解是,如果请求映射有两个匹配项,那么spring将使用更长的url选择handle方法。为什么spring mvc选择较短的映射?
给出以下映射:
/api/companies/{id}/records/cabinets/FileTypes/{fileTypeId}/{versionId}
已映射到method1 /api/**
已映射到method2 路径api/companies/2/records/cabinets/FileTypes/50/1
应该将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=[]}]
答案 0 :(得分:7)
我认为映射考虑了第一个表达式中括号的数量:
/api/companies/{id}/records/cabinets/FileTypes/{fileTypeId}/{versionId}
^-- ^-- ^--
由于第一个中有三个括号(模式),而第二个中只有一个模式(**
),因此第一个被认为是更一般的。
当*
和/*
以相同方式评估时,请尝试制作第二个表达式,而不是/api/**
,如:
/api/**/**/**/**
这有四种模式,因此比其他模式“更通用”。但实际上,它相当于/api/**
。这将使它最后评估。
由于存在这种有点“简单”的解决方法,我相信如果有的话,该错误需要很长时间才能得到纠正。
答案 1 :(得分: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网站上提交一张票。