Мы используем JSF 2.0 в WebSphere v8.5 с несколькими библиотеками компонентов PrimeFaces 4.0, Tomahawk 2.0, RichFaces и т. Д.

Я ищу общий механизм, чтобы избежать повторной отправки формы при обновлении страницы или при повторном нажатии кнопки отправки. У меня много приложений с разными сценариями.

На данный момент я подумал об отключении кнопки с помощью фрагмента JavaScript в атрибуте onclick, но это меня не устраивает. Я ищу для этой цели чистую реализацию Java, что-то вроде Struts2 <s:token>.

14
Sarz 25 Апр 2014 в 10:19

3 ответа

Лучший ответ

Я ищу общий механизм, чтобы избежать повторной отправки формы при обновлении страницы

Для этого есть как минимум 2 решения, которые нельзя комбинировать:

  1. Выполните редирект после синхронного поста. Таким образом, обновление будет повторно выполнять только перенаправленный запрос GET вместо первоначального запроса. Недостаток: вы больше не можете использовать область запроса для обратной связи с конечным пользователем. JSF 2.0 решил эту проблему, предложив новую вспышку. См. Также Как отобразить сообщение о лицах на перенаправленной странице .

  2. Выполняйте POST асинхронно в фоновом режиме (используя ajax). Таким образом, обновление будет повторно выполнять только первоначальный запрос GET, который открыл форму. Вам нужно только убедиться, что эти формы изначально открываются только запросом GET, т.е. вы никогда не должны выполнять переход от страницы к странице с помощью POST (что само по себе уже является плохим дизайном). См. Также Когда следует использовать h: outputLink вместо h: commandLink? < / а>


или при повторном нажатии кнопки отправки

Для этого есть как минимум 2 решения, которые при необходимости можно комбинировать:

  1. Просто заблокируйте для конечного пользователя возможность нажимать кнопку отправки во время отправки и / или после успешной отправки. Для этого есть несколько способов, все в зависимости от конкретных функциональных и дизайнерских требований. Вы можете использовать JavaScript, чтобы отключить кнопку во время отправки. Вы можете использовать атрибуты JSF disabled или rendered, чтобы отключить или скрыть кнопку после отправки. См. Также Как предотвратить двойное нажатие в JSF 2 . Вы также можете использовать оверлейное окно во время обработки запросов ajax, чтобы заблокировать любое взаимодействие конечного пользователя. Для этой цели PrimeFaces имеет <p:blockUI>.

  2. Проверить уникальность вновь добавленного объекта на стороне сервера. Это намного надежнее, если вы абсолютно хотите избежать дублирования по техническим причинам, а не по функциональным причинам. Это довольно просто: наложите ограничение UNIQUE на рассматриваемый столбец БД. Если это ограничение нарушается, то БД (и структура взаимодействия с БД, такая как JPA) выдаст исключение нарушения ограничения. Лучше всего это делать в сочетании с настраиваемым валидатором JSF, который заранее проверяет ввод, выполняя SELECT именно в этом столбце и проверяя, не возвращается ли запись. Валидатор JSF позволяет отображать проблему в виде сообщения с дружественными лицами. См. Также среди прочего Проверка формата и уникальности электронной почты по базе данных .

18
Community 23 Май 2017 в 12:10

Вместо того, чтобы создавать токен вручную, вы можете использовать решение BalusC. Он предложил шаблон Post-Redirect-GET в своем блоге < / а>

Альтернативные решения можно найти в этих ответах:

3
Manuel 7 Май 2014 в 08:43
<!--Tag to show message given by bean class -->
<p:growl id="messages" />

<h:form>
  <h:inputText a:placeholder="Enter Parent Organization Id" id="parent_org_id" value="#{orgMaster.parentOrganization}" requiredMessage="Parent org-id is required" />


  <h:commandButton style="margin-bottom:8px;margin-top:5px;" class="btn btn-success btn-block " value="Save" type="submit" action="#{orgMaster.save}" onclick="resetform()" />
</h:form>
    public String save() {
    FacesContext context = FacesContext.getCurrentInstance();
    context.getExternalContext().getFlash().setKeepMessages(true); //This keeps the message even on reloading of page

FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Your submission is successful.", " ")); // To show the message on clicking of submit button


return "organizationMaster?faces-redirect=true"; // to reload the page with resetting of all fields of the form.. here my page name is organizationMaster...you can write the name of form whose firlds you want to reset on submission

}
0
Vinod Chauhan 8 Сен 2018 в 06:13