避免多次提交表单

use*_*434 6 jsf-2

在JSF2中,有没有办法处理多表单提交(用户多次点击提交按钮)?现在我们在服务器中获得以下异常

java.lang.IllegalStateException: Response already committed
java.lang.IllegalStateException: Response already committed
javax.faces.FacesException: socket write error: Connection aborted by peer
Run Code Online (Sandbox Code Playgroud)

Bal*_*usC 4

这取决于您提交表格的方式。如果您使用<f:ajax>Ajax 或任何其他基于 Ajax 的标签来执行 Ajax 提交,那么最好的选择是添加jsf.ajax.addOnEvent()一个函数,该函数在 Ajax 请求即将发送时禁用该按钮,并在 Ajax 请求后重新启用该按钮。检索到响应。

例如,如下所示,您可以在包含 JSF Ajax 脚本之后将其包含在内,<script>例如在.<h:outputScript>.js<h:head>

jsf.ajax.addOnEvent(function(data) {
    if (data.source.type != "submit") {
        return; // Ignore anything else than input type="submit".
    }

    switch (data.status) {
        case "begin":
            data.source.disabled = true; // Disable input type="submit".
            break;
        case "complete":
            data.source.disabled = false; // Re-enable input type="submit".
            break;
    }    
});
Run Code Online (Sandbox Code Playgroud)

如果您使用 Ajax 执行提交,那么方法之一是添加一个setTimeout()函数,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)

setTimeout()是强制性的,因为当您立即禁用它时,这name=value对按钮将不会与请求一起发送,这将导致 JSF 无法识别要action执行的。当然,您可以将其重构为一些 DOM 就绪或窗口加载函数,该函数将其应用于所有提交按钮(jQuery 在这方面将非常有帮助)。