ManagedProperty不可用

时间:2014-06-30 18:55:25

标签: jsf managed-bean myfaces

我有两个ManagedBeans(SessionHandler和OrderHandler)。两者都是会话范围。

SessionHandler:

@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 & setter ...
}

OrderHandler:

@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语句中,accountID为null。 accountID = 1的语句(例如)有效。在预订过程的后期,我可以使用accountID(无需做任何重新声明或覆盖它)。

我想问题是,登录后该属性不可用......但我不知道为什么。有人能帮助我吗?

1 个答案:

答案 0 :(得分:0)

使用@ManagedProperty时,需要记住的一个重要事实是,在调用 bean构造函数之后,会注入一次这样的属性。原因是因为JSF只能在完全构造bean时注入属性。

实际上,这意味着,从您当前的代码开始,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