2012-05-04 34 views
1

我想在我的Grails应用程序中处理重复的表单提交。所以我设置在我的形式useToken="true",这是我尝试使用withForm方法在我的控制器:Grails - 重复的表单提交处理 - withForm {}如何工作?

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

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

对此的任何帮助将是非常有帮助的。 非常感谢您。

回答

2

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

Grails Manual显示如何使用它。

所有的逻辑确实是把一个隐藏的领域与一个独特的价值在它。该值存储在会话中,因此您的会话必须正常工作(并且如果在集群环境中托管,则需要会话亲缘关系或共享会话)。表单提交后,它会查找该唯一值,并确定它是否已提交。

您不会出现在任何地方处理的invalidToken,所以你可能会处理,其中令牌不被存储或传递正确的情况下,你的逻辑是造成重定向。如果您使用get而不是post重定向,则可能会导致重定向循环。 (即使令牌第一次正确处理,这可能会导致重定向循环。)

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

+1

谢谢! 我的操作是处理“POST”和“GET”方法。我从“withForm”范围中取出了“GET”部分,现在它工作正常。 –

1

答案就在问题 - “重复表单提交”,你有请求被发送到服务器,所以你必须处理他们两个

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

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

第二个请求仍包含与第一个请求相同的令牌,但服务器已将该令牌抛出,所以第二个请求使用'invalidToken'块中的代码,或者如果您省略了默认块'invalidToken'块。

很重要的一点就是 - 它是第二个(坏的)请求将决定什么是在浏览器中显示,因为它第一后到达,所以我已经决定了,在处理错误的请求,将用户重定向回到索引,他们应该能够看到第一个请求创建和保存的记录。 即

 }.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" 
} 

然后在索引中。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> 

此工程确定,并且是一般的好,你可以削减ñ粘贴到任何控制器,和index.gsp中,而无需进行自定义。