Spring MVC - 多个提交按钮到表单

Posted

技术标签:

【中文标题】Spring MVC - 多个提交按钮到表单【英文标题】:Spring MVC - Multiple submit button to a Form 【发布时间】:2012-01-21 16:05:49 【问题描述】:

我正在尝试将 2 个提交按钮发布到表单,每个按钮操作映射到不同的控制器。这是我的映射

@RequestMapping(value="/save", method=RequestMethod.POST, params="save")
@RequestMapping(value="/save", method=RequestMethod.POST, params="renew")

我的提交按钮看起来像这样 -

<input type="submit" name="save" class="button" value="Save" />
<input type="submit" name="renew" class="button" value="Renew" />

从我的映射中可以看出,我依靠使用参数来区分单击了哪个按钮。问题是它在 90% 的时间内都有效,但有时我会遇到以下异常 -

java.lang.IllegalStateException: Ambiguous handler methods mapped for HTTP path 'http://localhost:8090/myapp/save': public java.lang.String com.myapp.SaveController.save(MyEntity,javax.servlet.http.HttpSession), public java.lang.String com.myapp.SaveController.saveAndRenew(MyEntity,javax.servlet.http.HttpSession)
org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(AbstractHandlerMethodMapping.java:248)
org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:194)

奇怪的是,当这种情况发生并且我重新提交页面时,之后一切正常。有没有更好的方法来实现我想要做的事情?

谢谢!

【问题讨论】:

不确定是否是您的问题,但请记住,如果用户通过输入键或某些其他方法提交表单,除了单击按钮之外,某些浏览器不会发送任何按钮的键/值对。因此,请确保采用默认操作,为了浏览器兼容性,该操作需要是该表单的 html 源中的 第一个按钮 的操作。 【参考方案1】:

如果表单指定了这些按钮:

input type="submit" class="button" name="save" value="Save"
input type="submit" class="button" name="delete" value="Delete"
input type="submit" class="button" name="cancel" value="Cancel"

您可以根据一个控制器按下的按钮指向不同的 url 请求。

取消按钮,

@RequestMapping(params = "cancel", method = RequestMethod.POST)
public String cancelUpdateUser(HttpServletRequest request) 
    return "redirect:/users.html";

请求映射的作用是扫描包含参数 name = cancel 的 post 请求。

保存按钮,

@RequestMapping(params = "save", method = RequestMethod.POST)
public String saveUser(HttpServletRequest request, @ModelAttribute User user, BindingResult result, SessionStatus status) 
    // validate your result
    // if no errors, save it and redirect to successView.

【讨论】:

【参考方案2】:

为什么不:

<input type="submit" name="action" value="save" />

然后:

@RequestMapping(value="/save", method=RequestMethod.POST)
public String handlePost(@RequestParam String action)

    if( action.equals("save") )
       //handle save
    
    else if( action.equals("renew") )
       //handle renew
    

 

【讨论】:

似乎有点危险,因为input 标签上的value 属性包含按钮的文本。我认为 i18n 不会成为您使用这种方法的朋友。 我遇到了 IE (10) 无法一致发布值的问题,并采用了您的方法。虽然不是超干净,但它对我有用。干杯。【参考方案3】:

如果您有更多具有相同 @RequestMapping 且仅在 params 属性上有所不同的控制器方法,则必须明确编写:

哪个参数应该出现在请求中,例如params="save" 哪个参数不应该出现在请求中,例如params="!save"

在你的情况下:

@RequestMapping(value="/save", method=RequestMethod.POST, params="save", "!renew")
@RequestMapping(value="/save", method=RequestMethod.POST, params="renew", "!save")

这应该会修复错误为 HTTP 路径映射的不明确的处理程序方法 ...

见Spring Web API 4.0.x - RequestMapping#params

【讨论】:

【参考方案4】:

只需用类似的方法创建一个控制器

@RequestMapping(value="/save", method=RequestMethod.POST)
public String handlePost(@RequestParam(required=false , value = "save") String saveFlag , @RequestParam(required=false , value = "renew") String renewFlag)

if(saveFlag != null
   //handle save

else if(renewFlag !=null
   //handle renew


 

【讨论】:

【参考方案5】:

另一种解决方案:

@RequestMapping(value="/save", method=RequestMethod.POST, params="save=Save")
@RequestMapping(value="/save", method=RequestMethod.POST, params="renew=Renew")

【讨论】:

以上是关于Spring MVC - 多个提交按钮到表单的主要内容,如果未能解决你的问题,请参考以下文章

mvc多个按钮的提交方法

根据单击的提交按钮将表单发布到不同的 MVC 发布操作

由于 Spring MVC 中不存在 URL,验证表单提交按钮在第二次尝试后返回 404

转:MVC单表多按钮提交

在带有部分视图的 MVC 5 中将提交按钮移到表单之外

spring-mvc 如何把页面表单提交过来的值注入到对应的实体里面