如何防止Seam中的表单重新提交?

Jon*_*tow 6 java forms jsf seam

我有一个简单的表单,我不想多次意外提交.

我可以轻松阻止用户在第一次看到页面时多次点击,但我无法控制他们点击后退按钮.

因此,在使用Struts之后,我决定使用表单提交令牌.

有没有更简单的方法?这个功能已经在Seam中了吗?如果没有,我应该如何在Seam中构建此功能?

//编辑//这里只是澄清一下,我不需要能阻止用户双击的东西.那已经解决了.

具体用例如下:用户单击按钮.行动运行.将来一些未指定的时间,用户按下后退按钮足够的时间以使用按钮返回页面.用户再次单击该按钮.

我该如何防范?

Bal*_*usC 6

为了避免因不耐烦地按下提交按钮而导致的双重提交,您可以使用一段Javascript,在onclick后几毫秒禁用提交按钮.

例:

<h:commandButton 
    id="foo"
    value="submit"
    action="#{bean.submit}"
    onclick="setTimeout('document.getElementById(\'' + this.id + '\').disabled=true;', 50);"
/>
Run Code Online (Sandbox Code Playgroud)

要通过按后退按钮并忽略浏览器警告您可能有重新发送数据的风险来避免双重提交,您需要实现Post-Redirect-Get(PRG)模式.

在JSF中,这可以基本上以两种方式完成.使用<redirect/>in <navigation-case>:

<navigation-case>
    <from-action>#{bean.submit}</from-action>
    <from-outcome>success</from-outcome>
    <to-view-id>/page.jsf</to-view-id>
    <redirect/>
</navigation-case>
Run Code Online (Sandbox Code Playgroud)

或者通过调用ExternalContext#redirect()bean的action方法:

public void submit() {
    doYourThing();
    FacesContext.getCurrentInstance().getExternalContext().redirect("page.jsf");
}
Run Code Online (Sandbox Code Playgroud)

唯一的缺点是重定向隐式地创建了一个请求,因此包含了包含其所有属性的初始请求(因此也包括所有请求范围的托管bean FacesMessages).在某些情况下它并不重要,但在其他情况下肯定会.我不做Seam,但如果我是正确的,他们已经通过所谓的会话范围解决了这个问题,并FacesMessages通过重定向自动保留.你可以从中受益.