#jsf #managed-bean #myfaces
#jsf #управляемый компонент #myfaces #мои лица
Вопрос:
У меня есть два управляемых файла (SessionHandler и OrderHandler). Оба находятся в области сеанса.
Обработчик сеансов:
@ManagedBean(name="session")
@SessionScoped
public class SessionHandler {
private Account account;
public String login() {
try {
// ... login method ...
return("bookinglist.xhtml?faces-redirect=true");
}
catch (Exception e) {
// ... exception handling ...
}
}
// ... getter amp; setter ...
}
Обработчик заказов:
@ManagedBean(name="order")
@SessionScoped
public class OrderHandler {
@ManagedProperty(value="#{session.account}")
Account account; // getter and setter
public OrderHandler() {
this.createList();
}
private void createList() {
// method creates an ArrayList of bookings
// it uses this.account.getId() for a SQL statement
}
}
В bookinglist.xhtml я хочу отобразить текст приветствия и мой список:
<p>Welcome, #{sessions.account.name}!</p>
<ui:repeat value="#{order.bookingList}" var="item">
<!-- ... items ... --->
</ui:repeat>
Отображается текст приветствия, но мой список пуст, потому что в моей инструкции sql идентификатор учетной записи равен null. Работает инструкция с AccountId = 1 (в качестве примера). Позже в процессе бронирования я могу использовать идентификатор учетной записи (не делая ничего, чтобы повторно объявить или перезаписать его).
Я предполагаю, что проблема в том, что свойство недоступно сразу после входа в систему… Но я не знаю почему. Кто-нибудь может мне помочь?
Комментарии:
1. Как насчет создания «OrderHandler»
@RequestScoped
?2. Никакого эффекта… И мне нужно, чтобы OrderHandler был привязан к сеансу для других методов.
Ответ №1:
При использовании @ManagedProperty
следует иметь в виду один важный факт, который заключается в том, что такое свойство будет введено один раз после вызова конструктора bean. Причина в том, что JSF может вводить свойство только тогда, когда компонент полностью сконструирован.
По сути, это означает, что из вашего текущего кода account
будет введено после createList()
вызова. Если вы выполняете отладку OrderHandler
, вы, скорее всего, увидите следующую последовательность выполнения:
// bean instantiation step
-> OrderHandler constructor called
-> createList called
// bean property injection step
-> Account injected
Чтобы решить эту проблему, вам нужно вызвать createList()
после того, как конструктор завершен и account
уже введен. Вы можете достичь этого с помощью метода с @PostConstruct
аннотацией:
@PostConstruct
private void init() {
// this will be called after constructor call, and property injection
this.createList();
}
Вы можете прочитать больше о @PostConstruct
аннотации здесь:
http://docs.oracle.com/javaee/7/api/javax/annotation/PostConstruct.html