Spring Web MVC:对请求参数和路径变量使用相同的请求映射
Posted
技术标签:
【中文标题】Spring Web MVC:对请求参数和路径变量使用相同的请求映射【英文标题】:Spring Web MVC: Use same request mapping for request parameter and path variable 【发布时间】:2011-02-14 06:51:50 【问题描述】:有没有办法表示我的 Spring Web MVC 控制器方法应该通过将 ID 作为 URI 路径的一部分提交的请求来匹配...
@RequestMapping(method=RequestMethod.GET, value="campaigns/id")
public String getCampaignDetails(Model model, @PathVariable("id") Long id)
...或者如果客户端将 ID 作为 HTTP 请求参数以样式发送...
@RequestMapping(method=RequestMethod.GET, value="campaigns")
public String getCampaignDetails(Model model, @RequestParam("id") Long id)
在我看来,这似乎是一个非常常见的现实世界 URL 方案,我不想添加重复的代码,但我还没有找到答案。任何建议都非常受欢迎。
编辑:事实证明,目前似乎(使用 Spring MVC 没有办法实现这一点,请参阅 Javi 答案中的讨论。
【问题讨论】:
【参考方案1】:您可以为同一个函数设置映射 url 并将 id 设置为可选。
@RequestMapping(method=RequestMethod.GET, value="/campaigns","/campaigns/id")
public String getCampaignDetails(Model model,
@RequestParam(value="id", required=false) Long id,
@PathVariable("id") Long id2)
虽然在不发送 id 时它也会映射,但你可以在方法内部控制它。
编辑:之前的解决方案不起作用,因为在没有null
时,@PathVariable
未设置为 null
,并且它无法映射 URL(感谢 ngeek)。我认为唯一可能的解决方案是创建两个方法,每个方法都映射到其@MappingRequest
,并在其中一个调用另一个函数或重定向到另一个 URL(重定向:或转发:Spring 前缀)。我知道这个解决方案不是您想要的,但认为这是您能做的最好的。实际上,您不是在复制代码,而是在创建另一个函数来处理另一个 URL。
【讨论】:
不幸的是,这不起作用,因为路径变量无法解析。我还通过添加方法参数(@PathVariable("id") Long id2)尝试了一个变体,但是您不能将路径变量设为可选,因此这个建议的解决方案不起作用。还有其他推荐吗? @ngeek 我没有意识到@PathVariable 不能设置为空,谢谢。我也忘了写@PathVariable,所以我编辑了我的答案来添加它,我认为你不能避免有两种我认为的方法:(。 感谢您回到您的提议 Javi。当然,我已经委托了相同的内部方法以避免重复代码。我仍然认为 Spring MVC 注释应该提供一种方法来通过内在方法将多个 URL 定义映射到同一个方法,就像 Rails 或 Grails 中的路由器已经允许的那样。无论如何感谢您的帮助。 这个例子让我有点困惑,因为我添加了一个 id2。其他对此感到困惑的人可能会很高兴知道这是有效的:@PathVariable @RequestParam(value = "id", required = false) Long id, @OutfastSource@PathVariable
在我这样做时似乎被忽略了。对我有用的是@Javi 在@PathVariable
中对required = false
的回答,自Spring MVC 4.3.3 起支持。【参考方案2】:
如果您仍想坚持使用 PathVariable 方法并且遇到 400 句语法不正确的错误,请遵循此方法-
@RequestMapping(method=RequestMethod.GET, value="campaigns/id","campaigns")
public String getCampaignDetails(Model model,
@PathVariable Map<String, String> pathVariables)
System.out.println(pathVariables.get("id"));
【讨论】:
【参考方案3】:@RequestMapping
注解现在支持设置path
属性,而不是name
或value
。使用path
,可以实现本题想要的映射:
@RequestMapping(method=RequestMethod.GET, path="campaigns/id")
public String getCampaignDetails(Model model, @PathVariable("id") Long id)
@RequestMapping(method=RequestMethod.GET, value="campaigns")
public String getCampaignDetails(Model model, @RequestParam("id") Long id)
【讨论】:
以上是关于Spring Web MVC:对请求参数和路径变量使用相同的请求映射的主要内容,如果未能解决你的问题,请参考以下文章