【问题标题】:JSF 2 : Accessing managed bean's instance in the phase listener object?JSF 2:在阶段侦听器对象中访问托管 bean 的实例?
【发布时间】:2010-11-29 12:55:28
【问题描述】:

是否可以在 before-invokeApplication-phaselistener 中获取对待执行 managedbean 的引用?

在调用应用阶段之前,应该明确哪个 managedBean 将执行该方法。

为了这个例子,假设有 1 个主管理 bean 来处理 1 个 jsf 页面。

所以我需要的基本上是:

  1. 用户从菜单访问程序
  2. 因为它是从菜单访问的,所以会调用主管理 bean 的 init() 方法来初始化诸如准备数据、进行授权检查等内容
  3. 在从菜单重新访问之前,后续提交不再需要调用 init() 方法

为了实现第 2 点,我正在考虑拦截其中一个阶段

我查看了有关在阶段实现中获取托管 bean 的 API 文档,但我似乎找不到任何内容。

输入这个问题后,我意识到我可以在 @PostConstruct 或托管 bean 的构造函数中执行此操作,但这只会在第一次构造 bean 时执行,我需要在每次 jsf 被调用时调用该方法从菜单访问。

有什么建议吗?

问候,
阿尔伯特·坎

【问题讨论】:

    标签: jsf jsf-2


    【解决方案1】:

    您可以通过 ELContext/ELResolver 访问您的托管 bean。 MyFaces wiki 很好地解释了这一点(也适用于原版 JSF)。

    例如:

    ELContext elContext = FacesContext.getCurrentInstance().getELContext();
    NeededBean neededBean = (NeededBean) FacesContext.getCurrentInstance().getApplication()
        .getELResolver().getValue(elContext, null, "neededBean");
    

    请参阅MyFaces wiki entry 以获得进一步的解释,以及其他 JSF 版本的实现。

    您使用@PostConstruct 的想法很好。考虑将您的范围更改为类似@ViewScoped 的内容,这样每次导航到该视图时都会执行该逻辑。

    另外,请查看PreRenderViewEvent(适用于 JSF 2)。此代码嵌入在您的 facelet 页面中:

    <f:metadata>
    <f:viewParam name="foo" value="#{bean.foo}"/>
    <f:event type="preRenderView" listener="#{bean.doSomething}"/>
    </f:metadata>
    

    f:event 监听器在每次页面查看之前执行。

    【讨论】:

    • 我看不出它是如何准确返回 action 方法中涉及的实例的。您的方法要求事先已经知道 bean 名称。顺便说一句,我更喜欢Application#evaluateExpressionGet() 速记而不是ELResolver/ELContext。另请参阅this answer
    • 好吧,如果他的阶段侦听器在调用应用程序之前的阶段进行侦听,那么阶段侦听器将实例化对象实例。这个相同的实例将在应用程序方法中引用(在调用应用程序阶段被调用),因为托管的 be 仍在范围内(相同的请求)。我回答了如何做到这一点的问题,但我不主张将其作为最佳解决方案。我提供了似乎更适合实现最终目标的替代方案。
    猜你喜欢
    • 2013-09-06
    • 1970-01-01
    • 1970-01-01
    • 2012-03-24
    • 2013-03-12
    • 1970-01-01
    • 1970-01-01
    • 2011-11-28
    • 2012-08-27
    相关资源
    最近更新 更多