用于双重提交预防的纯Java / JSF实现

问题描述 投票:14回答:3

我们在WebSphere v8.5上使用JSF 2.0,其中有几个组件库PrimeFaces 4.0,Tomahawk 2.0,RichFaces等。

我正在寻找通用机制,以避免刷新页面时重新提交表单,或者再次单击提交按钮时。我有许多不同场景的应用程序。

现在我已经考虑过用onclick属性中的一段JavaScript来禁用该按钮,但这并不令人满意。我正在寻找一个用于此目的的纯Java实现,类似于Struts2 <s:token>

jsf form-submit double-submit-prevention
3个回答
17
投票

我正在寻找通用机制,以避免刷新页面时重新提交表单

为此,至少有两种解决方案无法组合:

  1. 在同步发布后执行重定向。这样刷新只会重新执行重定向的GET请求而不是初始请求。缺点:您不能再使用请求范围来向最终用户提供任何反馈。 JSF 2.0通过提供新的flash scope解决了这个问题。另见How to show faces message in the redirected page
  2. 在后台异步执行POST(使用ajax)。这样刷新只会重新执行打开表单的初始GET请求。您只需要确保这些表单最初只是通过GET请求打开,即您永远不应该通过POST执行页面到页面的导航(无论如何,它本身已经是一个糟糕的设计)。另见When should I use h:outputLink instead of h:commandLink?

或者再次点击提交按钮时

为此,基本上还有至少2个解决方案,必要时可以组合使用:

  1. 只是阻止最终用户在提交期间和/或成功提交后按下提交按钮。有各种方法,这取决于具体的功能和设计要求。您可以使用JavaScript在提交期间禁用该按钮。您可以使用JSF的disabledrendered属性在提交后禁用或隐藏按钮。另见How to do double-click prevention in JSF 2。您还可以在处理ajax请求期间使用覆盖窗口来阻止任何最终用户交互。 PrimeFaces有<p:blockUI>为目的。
  2. 验证服务器端新添加的实体的唯一性。如果您出于技术原因而非出于功能原因而绝对希望避免重复,则这种方法会更加强大。这很简单:在有问题的DB列上放置一个UNIQUE约束。如果违反了此约束,则DB(和JPA等数据库交互框架)将抛出约束违例异常。最好与自定义JSF验证器结合使用,该验证器通过在该列上执行SELECT并检查是否未返回任何记录来预先验证输入。 JSF验证器允许您显示友好面部消息的风格问题。另见Validate email format and uniqueness against DB

3
投票

您可以使用BalusC的解决方案,而不是手动创建令牌。他在his blog提出了Post-Redirect-GET模式

在这些答案中可以找到替代解决方案:


0
投票

<!--Tag to show message given by bean class -->
<p:growl id="messages" />

<h:form>
  <h:inputText a:placeholder="Enter Parent Organization Id" id="parent_org_id" value="#{orgMaster.parentOrganization}" requiredMessage="Parent org-id is required" />


  <h:commandButton style="margin-bottom:8px;margin-top:5px;" class="btn btn-success btn-block " value="Save" type="submit" action="#{orgMaster.save}" onclick="resetform()" />
</h:form>
    public String save() {
    FacesContext context = FacesContext.getCurrentInstance();
    context.getExternalContext().getFlash().setKeepMessages(true); //This keeps the message even on reloading of page

FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Your submission is successful.", " ")); // To show the message on clicking of submit button


return "organizationMaster?faces-redirect=true"; // to reload the page with resetting of all fields of the form.. here my page name is organizationMaster...you can write the name of form whose firlds you want to reset on submission

}
© www.soinside.com 2019 - 2024. All rights reserved.