我们在WebSphere v8.5上使用JSF 2.0,其中有几个组件库PrimeFaces 4.0,Tomahawk 2.0,RichFaces等。
我正在寻找通用机制,以避免在刷新页面或再次单击提交按钮时重新提交表单。我有许多不同场景的应用程序。
目前我已考虑在onclick
属性中使用一段JavaScript禁用该按钮,但这并不令人满意。我正在寻找一个用于此目的的纯Java实现,类似于Struts2 <s:token>
。
答案 0 :(得分:17)
我正在寻找通用机制,以避免在刷新页面时重新提交表单
为此,至少有两种解决方案无法合并:
在同步发布后执行重定向。这样刷新只会重新执行重定向的GET请求而不是初始请求。缺点:您不能再使用请求范围来向最终用户提供任何反馈。 JSF 2.0通过提供新的flash scope解决了这个问题。另请参阅How to show faces message in the redirected page。
在后台异步执行POST(使用ajax)。这样刷新只会重新执行打开表单的初始GET请求。您只需要确保这些表单最初只是通过GET请求打开,即您永远不应该通过POST执行页面到页面的导航(无论如何,它本身已经是一个糟糕的设计)。另请参阅When should I use h:outputLink instead of h:commandLink?
或再次点击提交按钮时
为此,基本上还有至少2个解决方案,如果有必要可以合并:
阻止最终用户在提交期间和/或成功提交后按下提交按钮。有各种方法,这取决于具体的功能和设计要求。您可以使用JavaScript在提交期间禁用该按钮。您可以使用JSF的disabled
或rendered
属性在提交后禁用或隐藏按钮。另见How to do double-click prevention in JSF 2。您还可以在处理ajax请求期间使用覆盖窗口来阻止任何最终用户交互。 PrimeFaces的目的是<p:blockUI>
。
验证服务器端新添加的实体的唯一性。如果您出于技术原因而非出于功能原因而绝对希望避免重复,则这种方法会更加强大。这很简单:在有问题的DB列上加上UNIQUE
约束。如果违反了此约束,则DB(和JPA等数据库交互框架)将抛出约束违例异常。最好与自定义JSF验证器结合使用,该验证器通过在该列上执行SELECT
并检查是否未返回任何记录来预先验证输入。 JSF验证器允许您显示友好面部消息的风格问题。另请参见Validate email format and uniqueness against DB。
答案 1 :(得分:3)
您可以使用BalusC&#39;而不是手动创建令牌。解。他在his blog
中提出了Post-Redirect-GET模式在这些答案中可以找到替代解决方案:
答案 2 :(得分: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
}