Как предотвратить повторную отправку формы в Seam? - PullRequest
6 голосов
/ 17 ноября 2009

У меня есть простая форма, которую я не хочу случайно отправлять несколько раз.

Я могу легко заблокировать пользователя от нескольких кликов, когда они впервые видят страницу, но я не могу контролировать их, нажимая кнопку "Назад".

Итак, поработав со Struts, я решил, что путь для отправки формы - это то, что нужно.

Есть ли более простой способ? Эта функциональность уже есть в Seam? Если нет, то как мне встроить эту функцию в Seam?

// РЕДАКТИРОВАТЬ // Просто пояснение, мне НЕ нужно что-то, что удержит пользователя от двойного щелчок. Это уже решено.

Конкретный вариант использования выглядит следующим образом: Пользователь нажимает кнопку. Действие бежит. Некоторое неопределенное время в будущем, пользователь нажимает кнопку «Назад» достаточно раз, чтобы вернуться на страницу с помощью кнопки. Пользователь снова нажимает кнопку.

Как мне защититься от этого?

Ответы [ 3 ]

6 голосов
/ 08 декабря 2009

Seam поставляется с компонентом s: token, и это то, что вы ищете: http://docs.jboss.org/seam/2.2.0.GA/reference/en-US/html/controls.html#d0e28933

6 голосов
/ 17 ноября 2009

Чтобы избежать двойной отправки, вызванной нетерпеливым нажатием кнопки отправки, вы можете использовать фрагмент 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 через перенаправление. Вы могли бы воспользоваться этим.

2 голосов
/ 18 ноября 2009

В a4j / RichFaces используйте очередь a4j: или назначьте очередь кнопке. Таким образом, несколько кликов будут поставлены в очередь, и фактически только один будет проходить. Если вы используете RichFaces (если мы это делаем вместо того, чтобы настраивать очередь повсеместно), способ установить его глобально для вашего приложения - добавить в ваш файл web.xml следующее:

<context-param>
    <param-name>org.richfaces.queue.global.enabled</param-name>
    <param-value>true</param-value>
</context-param>
...