【问题标题】:Accessing @SessionScoped @ManagedBean class in ExternalContext#getSessionMap() returns null在 ExternalContext#getSessionMap() 中访问 @SessionScoped @ManagedBean 类返回 null
【发布时间】:2015-04-27 07:44:28
【问题描述】:

我试图从 ManagedBeanUtil 类中获取我的 SessionScoped managedBean 的对象,但我得到的所有对象都是空的。

这是我的代码:-

package com.beas.ui.manager;
@ManagedBean(name = "sessionManager")
@SessionScoped
public class SessionManager implements Serializable {
private static final long serialVersionUID = -3064514740080155761L;

//..
}

public class ManagedBeanUtil {

public static SessionManager getSessionManager() {

    return (SessionManager) FacesContext.getCurrentInstance()
            .getExternalContext().getSessionMap().get("sessionManager"); // returns null
}
}

我不知道我做错了什么。谁能为此提供合适的解决方案?

【问题讨论】:

  • 为什么要这样访问bean而不是注入?
  • 我访问 sessionManager @erencan 的方式有问题。

标签: jsf managed-bean session-scope


【解决方案1】:

当您以“原始”方式访问它时,当 JSF 尚未(自动)创建 bean 时,它将返回 null

如果您想确保 JSF 自动创建 bean,那么您应该通过 Application#evaluateExpressionGet() 等将其评估为 EL 表达式来访问它:

public static SessionManager getSessionManager() {
    FacesContext context = FacesContext.getCurrentInstance();
    return (SessionManager) context.getApplication().evaluateExpressionGet(context, "#{sessionManager}", SessionManager.class);
}

但是,规范(并且更具声明性)的方式是将其作为@ManagedProperty 注入目标 bean(其在幕后的作用与上述基本相同)。

@ManagedBean
@RequestScoped
public class SomeBean {

    @ManagedProperty("#{sessionManager}")
    private SessionManager sessionManager; // +setter
}

CDI @Named+@Inject 不需要设置器和注释值,使其更干净。

@Named
@RequestScoped
public class SomeBean {

    @Inject
    private SessionManager sessionManager;
}
@Named
@SessionScoped
public class SessionManager implements Serializable {

}

【讨论】:

  • 很抱歉这么晚才回复,但 sessionManager 托管 bean 已在会话范围内声明。所以我们可以通过 getSessionMap() 方法访问 managedBean。它实际上对我有用,但这次不行:(
  • 嗯?您是否阅读并理解了答案?第一句话已经解释了它何时返回null。此后,答案显示了无论如何您如何获得它。或者您的意思是回复其他人的评论?
  • 是的,请阅读您的答案。但我担心的是为什么 bean 还没有创建它应该是。使用 getSessionMap() 有什么问题。
  • 当会话范围的 JSF 托管 bean 没有在 EL 中通过 #{managedBeanName} 事先在同一个会话中引用时,就会发生这种情况。当第一次在 EL 中引用会话范围的 JSF 托管 bean 时,例如因为它在 JSF 页面中被引用,所以 JSF 将自动创建实例并将其放入会话映射中,并以托管 bean 名称作为键。只有在那一刻之后,它才能像您最初那样通过会话映射在会话的剩余部分中可用。如果不可用,仅仅试图从会话映射中获取它不会自动创建 bean 实例。
猜你喜欢
  • 1970-01-01
  • 2015-01-10
  • 2012-02-07
  • 2013-02-06
  • 2019-06-04
  • 1970-01-01
  • 1970-01-01
  • 2014-11-05
  • 1970-01-01
相关资源
最近更新 更多