Чтобы избежать двойной отправки, вызванной нетерпеливым нажатием кнопки отправки, вы можете использовать фрагмент Javascript, который отключает кнопку отправки через несколько мс после нажатия кнопки мыши.
Пример:
<h:commandButton
id="foo"
value="submit"
action="#{bean.submit}"
onclick="setTimeout('document.getElementById(\'' + this.id + '\').disabled=true;', 50);"
/>
Чтобы избежать двойной отправки, нажав кнопку «Назад» и игнорируя предупреждение браузера о том, что вы рискуете повторно отправить данные, вам необходимо реализовать шаблон Post-Redirect-Get (PRG) .
В JSF это можно сделать двумя способами. Либо используя <redirect/>
в <navigation-case>
:
<navigation-case>
<from-action>#{bean.submit}</from-action>
<from-outcome>success</from-outcome>
<to-view-id>/page.jsf</to-view-id>
<redirect/>
</navigation-case>
или путем вызова ExternalContext#redirect()
в методе действия bean-компонента:
public void submit() {
doYourThing();
FacesContext.getCurrentInstance().getExternalContext().redirect("page.jsf");
}
Единственным недостатком является то, что перенаправление неявно создает новый запрос, тем самым обрабатывая начальный запрос, включая все его атрибуты (и, следовательно, также все управляемые bean-объекты и FacesMessages
). В некоторых случаях это не имеет значения, но в других случаях это, безусловно, будет. Я не делаю Seam, но если я прав, они решили эту проблему с помощью так называемой области диалога и автоматически сохраняют FacesMessages
через перенаправление. Вы могли бы воспользоваться этим.