Непосредственный атрибут в JSF обычно неправильно понимается. Если вы мне не верите, проверьте переполнение стека . Частичная путаница, вероятно, связана с тем, что они немедленно доступны как для входных (т.е. <h: inputText />), так и для командных (т. Е. <H: commandButton />) компонентов, каждый из которых по-разному влияет на жизненный цикл JSF.
Вот стандартный жизненный цикл JSF:
В этой статье я предполагаю, что вы знакомы с основами жизненного цикла JSF. Если вам нужно введение или обновление памяти, посмотрите Учебное пособие по Java EE 6 — Жизненный цикл приложения JavaServer Faces .
Примечание: примеры кода в этой статье предназначены для JSF 2 (Java EE 6), но принципы одинаковы для JSF 1.2 (Java EE 5).
немедленный = true для компонентов Command
В стандартном жизненном цикле JSF атрибут действия в компоненте Command оценивается на этапе вызова приложения . Например, скажем, у нас есть объект User / bean:
|
01
02
03
04
05
06
07
08
09
10
11
|
public class User implements Serializable { @NotBlank @Length(max = 50) private String firstName; @NotBlank @Length(max = 50) private String lastName; /* Snip constructors, getters/setters, a nice toString() method, etc */} |
И UserManager, который будет служить нашим управляемым компонентом:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
@SessionScoped@ManagedBeanpublic class UserManager { private User newUser; /* Snip some general page logic... */ public String addUser() { //Snip logic to persist newUser FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("User " + newUser.toString() + " added")); return "/home.xhtml"; } |
И базовая страница Facelets, newUser.xhtml , для визуализации представления:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
<h:form> <h:panelGrid columns="2"> <h:outputText value="First Name: " /> <h:panelGroup> <h:inputText id="firstName" value="#{userManager.newUser.firstName}" /> <h:message for="firstName" /> </h:panelGroup> <h:outputText value="Last Name: " /> <h:panelGroup> <h:inputText id="lastName" value="#{userManager.newUser.lastName}" /> <h:message for="lastName" /> </h:panelGroup> </h:panelGrid> <h:commandButton value="Add User" action="#{userManager.addUser()}" /></h:form> |
Которые все объединяются, чтобы произвести эту прекрасную форму:
Когда пользователь нажимает кнопку « Добавить пользователя» , на этапе Invoke Application будет вызван # {userManager.addUser} ; это имеет смысл, потому что мы хотим, чтобы поля ввода были проверены, преобразованы и применены к newUser до его сохранения.
Теперь давайте добавим кнопку «Отмена» на страницу, если пользователь передумает. Мы добавим еще одну <h: commandButton /> на страницу:
|
1
2
3
4
5
6
|
<h:form> <!-- Snip Input components --> <h:commandButton value="Add User" action="#{userManager.addUser()}" /> <h:commandButton value="Cancel" action="#{userManager.cancel()}" /></h:form> |
И метод cancel () для UserManager :
|
1
2
3
4
5
6
7
8
|
public String cancel() { newUser = new User(); FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Cancelled new user")); return "/home.xhtml";} |
Выглядит хорошо, правда? Но когда мы на самом деле пытаемся использовать кнопку отмены, мы получаем сообщения об ошибках, требующие ввода имени и фамилии:
Это связано с тем, что # {userManager.cancel} не вызывается до фазы вызова приложения , которая происходит после фазы проверки процесса ; так как мы не ввели имя и фамилию, проверки не прошли до вызова # {userManager.cancel} , а ответ будет обработан после фазы проверки процесса .
Мы, конечно, не хотим требовать от конечного пользователя ввести действительного пользователя перед отменой! К счастью, JSF предоставляет непосредственный атрибут для компонентов Command. Если для компонента Instant установлено значение true в компоненте Command, действие вызывается на этапе применения значений запроса :
Это идеально подходит для нашего варианта отмены. Если мы добавим немедленное = true в Cancel, # {userManager.cancel} будет вызван на этапе применения значений запроса , прежде чем произойдет какая-либо проверка.
|
1
2
3
4
5
6
|
<h:form> <!-- Snip Input components --> <h:commandButton value="Add User" action="#{userManager.addUser()}" /> <h:commandButton value="Cancel" action="#{userManager.cancel()}" immediate="true" /></h:form> |
Поэтому теперь, когда мы нажимаем кнопку «Отмена», на этапе « Применить значения запроса» вызывается # {userManager.cancel} , и мы возвращаемся на домашнюю страницу с ожидаемым сообщением об отмене; нет ошибок проверки!
А как насчет компонентов ввода?
Входные компоненты также имеют непосредственный атрибут, который также перемещает всю их логику в фазу Применить значения запроса . Однако поведение немного отличается от компонентов Command, особенно в зависимости от того, успешно ли выполнена проверка на компоненте Input. Моя следующая статья будет посвящена немедленному = true для компонентов ввода. На данный момент, вот предварительный просмотр того, как затрагивается жизненный цикл JSF:
Ссылка: JSF и «непосредственный» атрибут — командные компоненты от нашего партнера JCG Джерри Орра из блога Jerry on Java .






