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

Sar*_*arz 14 jsf form-submit double-submit-prevention

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

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

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

Bal*_*usC 17

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

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

  1. 在同步发布后执行重定向.这样刷新只会重新执行重定向的GET请求而不是初始请求.缺点:您不能再使用请求范围来向最终用户提供任何反馈.JSF 2.0通过提供新的闪存范围解决了这个问题.另请参阅如何在重定向页面中显示面部消息.

  2. 在后台异步执行POST(使用ajax).这样刷新只会重新执行打开表单的初始GET请求.您只需要确保这些表单最初只是通过GET请求打开,即您永远不应该通过POST执行页面到页面导航(无论如何,它本身已经是一个糟糕的设计).另请参见何时使用h:outputLink而不是h:commandLink?


或者再次点击提交按钮时

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

  1. 只是阻止最终用户在提交期间和/或成功提交后按下提交按钮.有各种方法,这取决于具体的功能和设计要求.您可以使用JavaScript在提交期间禁用该按钮.您可以使用JSF disabledrendered属性在提交后禁用或隐藏按钮.另请参阅如何在JSF 2中执行双击预防.您还可以在处理ajax请求期间使用覆盖窗口来阻止任何最终用户交互.PrimeFaces就是<p:blockUI>出于此目的.

  2. 验证服务器端新添加的实体的唯一性.如果您出于技术原因而非出于功能原因而绝对希望避免重复,则这种方法会更加强大.这很简单:对有UNIQUE问题的DB列施加约束.如果违反了此约束,则DB(和JPA等数据库交互框架)将抛出约束违例异常.最好与自定义JSF验证程序结合使用,该验证程序通过SELECT在该列上执行完整操作并检查是否未返回任何记录来预先验证输入.JSF验证器允许您显示友好面部消息的风格问题.另请参阅验证针对数据库的电子邮件格式和唯一性.