3

I am haunting a hard to reproduce bug of my jsf application (Mojarra 2.1 on Glassfish 3.0.1 with Primefaces 2.1, SSL). I have the suspicion that it might have something to do with double or multiple submission of the same form, e.g. when a user double clicks a submit button.

The symptoms of this bug are that the server interrupts the transmission of resource files (javascript, css) and the page then will look strange (missing css) or will not work as expected (missing js).

I am not sure that this is the only reason. This is hard to figure out since the error happens very occasionally.

Is there a way to prevent multiple submission of the same form? A javascript solution would do it. But maybe there is a server side solution, maybe a specific jsf configuration?

Matt Handy
  • 29,855
  • 2
  • 89
  • 112
  • To be sure, it were the endusers who complained that the page looks strange and/or didn't work as expected? Or was that just your own assumption based on the aborted resource requests? Btw: this cannot be solved by preventing "double submission". It's the final response which counts. – BalusC Nov 14 '11 at 20:20
  • Correct: End users complained and the only case we could reproduce the problem was if we double clicked on submit buttons (although end users denied that they had double clicked ...). – Matt Handy Nov 14 '11 at 20:23
  • I do understand the aborted resource requests of the 1st submit when the 2nd submit takes place, but I do not understand that the final response of the 2nd submit results in malformed CSS/JS. Aren't those resource requests re-requested? Have you tested it in more than one webbrowser? If all exposes the same misbehaviour, I'd start suspecting PrimeFaces. I am however not sure what kind of answer you expect. JSF/PrimeFaces does not offer builtin configurations/tags to prevent double submissions. You also seem to already know how to handle it with JS. – BalusC Nov 14 '11 at 20:30
  • Yes, Primefaces is one of my suspects. Since this problem apparently occured after upgrading to Primefaces 2.1, but I cannot certainly state that it wouldn't have happened with the previous version. (I know that primefaces css resource loading mechanism changed from 2.0 to 2.1). The problem happens with IE and Firefox, not in Chrome. I read [something about Seam](http://stackoverflow.com/q/1750625/620338) and thought there might be something similar for JSF. – Matt Handy Nov 14 '11 at 20:40
  • Yes, Seam comes with a ``. Under the covers, it's not that complicated. On prerender, an extra hidden input field with a per-session unique value is appended and at early stage as possible of form submit request processing, the presence of this token is checked in session and the request will be continued or ignored depending on its presence. When the response is finished, the token is removed from session. However, that would only prevent real double submits (business logic being executed twice), but not aborted/broken resource requests (they do not involve the hidden token value). – BalusC Nov 14 '11 at 20:46
  • (cont'd) So, I think that using some JS on `jsf.ajax.addOnEvent` to disable/re-enable the form's buttons is much easier/better. – BalusC Nov 14 '11 at 20:48

1 Answers1

2

I would in this particular case prefer a JavaScript solution over a server side solution. A server side solution would only prevent the business logic from being executed twice. It wouldn't prevent from the HTTP requests being sent twice, nor would it prevent the resource requests from being aborted. I do not think that this changes anything to the particular problem of the second submit coming with broken resources.

You can use the jsf.ajax.addOnEvent function to have a global hook on ajax requests. Here's a kickoff example:

jsf.ajax.addOnEvent(function(data) {
    if (data.source.type != "submit") {
        return;
    }

    switch (data.status) {
        case "begin":
            data.source.disabled = true;
            break;
        case "complete":
            data.source.disabled = false;
            break;
    }    
});
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks BalusC. A global solution sounds good. Is there a similar function for full requests? – Matt Handy Nov 16 '11 at 07:16
  • No, unfortunately not. You'd need to collect all submit buttons manually (jQuery?) and disable the button after a little timeout. See also for example http://stackoverflow.com/questions/2830542/prevent-double-submission-of-forms-in-jquery and http://stackoverflow.com/questions/2831464/using-jquery-to-prevent-resubmitting-form – BalusC Nov 16 '11 at 12:44