【问题标题】:Spring Web MVC: Use same request mapping for request parameter and path variableSpring Web MVC:对请求参数和路径变量使用相同的请求映射
【发布时间】: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 答案中的讨论。

【问题讨论】:

    标签: java spring spring-mvc annotations


    【解决方案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) {
      

      【讨论】:

        猜你喜欢
        • 2023-04-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-06
        • 1970-01-01
        • 2016-01-04
        • 2011-12-08
        相关资源
        最近更新 更多