Grails - 重复表单提交处理 - withForm {}如何工作?

时间:2012-05-04 01:02:17

标签: forms grails duplicates form-submit

我正在尝试在Grails应用中处理重复的表单提交。所以我在表单中设置了useToken="true",这就是我尝试在控制器中使用withForm方法的方法:

def myControllerAction {
    withForm {
       *my action's logic*
    }
}

但是,我最终使用:Error 310 (net::ERR_TOO_MANY_REDIRECTS): There were too many redirects.在我的浏览器中。 所以我想我没有正确使用它,我没有在网上找到任何关于如何正确使用该方法的例子。

对此的任何帮助都会非常有帮助。 提前谢谢你。

2 个答案:

答案 0 :(得分:2)

你的例子中没有多少:简短的回答是,如果令牌无效,你必须做一些事情来导致重定向。

Grails Manual显示了如何使用它。

所有逻辑都是一个带有唯一值的隐藏字段。该值存储在会话中,因此您的会话必须正常工作(如果在群集环境中托管,则需要会话关联或共享会话)。提交表单时,它会查找该唯一值,并确定它是否已提交。

您似乎没有在任何地方处理invalidToken,因此您可能正在处理令牌未正确存储或传递的情况,并且您的逻辑正在导致重定向。如果您使用get而不是post进行重定向,则可能会导致重定向循环。 (即使第一次正确处理 令牌,这也可能导致重定向循环。)

我会查看您的代码并找出重定向的来源。它不是由令牌直接引起的。

答案 1 :(得分:1)

答案是问题 - “重复表单提交”,您有两个请求发送到服务器,因此您必须处理两者他们。

因此,从浏览器向服务器发送了两个相同的请求,因此将调用该操作两次。

第一个请求将成功,并使用'withForm'块中的代码,并且令牌将递增。

第二个请求仍然包含与第一个请求相同的令牌,但服务器已抛弃该令牌,因此第二个请求使用'invalidToken'块中的代码,如果您省略了'',则使用默认块invalidToken'block。

重要的一点是 - 它是第二个(坏)请求,它将指示浏览器上显示的内容,因为它在第一个之后到达,因此我已经决定在处理错误请求时重定向用户到索引,他们应该能够看到第一个请求创建和保存的记录。 即

     }.invalidToken 
 {
    println "myController: swallowing request with invalidToken (probably a double-click or due to using back button in browser.)"
    flash.invalidToken = " " // just enough to trigger the g:if in the index.gsp
    redirect action:"index", method:"GET"
 }

然后在index.gsp中,我显示一条消息:

<g:if test="${flash.invalidToken}">
<ul class="errors" role="alert">
<li>
    <g:message code="error.doubleclick" 
           default="oops, the item you are creating exists already (maybe you double-clicked on the 'Save' button ?).  Click on the item in the list below to continue working with that item."
/>
</li>
</ul>

这个工作正常,并且足够通用,你可以将n个粘贴到任何控制器和index.gsp中,而不必自定义它。