JSF 2.0:在呈现视图之前未更新数据

时间:2012-07-25 13:18:30

标签: java jsf-2 updates

在我的应用程序中,我有以下bean:

@Named(value = "mrBean")
@SessionScoped
public class MrBean implements Serializable {

    @EJB
    private MrsBean mrsBean;

    private Item item;

    public void updateItem() {
        this.item = mrsBean.updateItem(item.getId());
    }

}

@Named(value = "itemBean")
@RequestScoped
public class itemBean {
    @Inject
    private MrBean mrBean;

    @PostConstruct
    public void init() {
        if (FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("update") != null) mrBean.updateItem();
    }
}

在显示ViewItem.xhtml页面上的项目信息之前,我会检查是否提交了update参数以在显示之前更新项目。

当我使用参数update=true测试页面时,我不知道为什么渲染旧数据而不是新更新的数据。实际上,我必须在呈现新数据之前刷新页面。

从上面的结果中,我想知道在呈现视图后是否调用了@PostConstruct方法。

如果你能给我一个建议,我将非常感激。

致以最诚挚的问候,

2 个答案:

答案 0 :(得分:2)

如果在 #{itemBean}之后的视图中第一次引用了#{mrBean.item},就会发生这种情况。 E.g。

#{mrBean.item}
...
#{itemBean}

当EL表达式首次引用它时,第一次构造托管bean,但它尚未在范围内存在。在GET请求中,其中托管bean实例未被taghandler属性或f:event引用,那么它只会在呈现响应期间构建。

如果重新排列它们以便在引用 #{itemBean}之前始终引用(并因此构造) ,那么最好使{{1} } #{mrBean.item} @PostConstruct代替。{/ p>

#{itemBean}

答案 1 :(得分:1)

我正在发布另一种解决方案,以防它对您有所帮助。您可以通过在每次要呈现页面时调用初始化方法来尝试不同的方法,并避免让请求bean进行更新。将此元数据标记添加到xhtml:

<f:metadata>
    <f:event type="preRenderView" listener="#{mrBean.init}" />
</f:metadata> 

在你的MrBean中,定义这个方法:

public void init() {
    if(!FacesContext.getCurrentInstance().isPostback() && FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("update") != null) 
        mrBean.updateItem();
}

这样,每次呈现ViewItem页面时都会执行updateItem检查。如果您的MrBean是ViewScoped而不是SessionScoped,我建议改为使用@PostConstruct注释。