Jpa 如何在PhaseListener中访问@Named bean?

Jpa 如何在PhaseListener中访问@Named bean?,jpa,jsf-2,cdi,named,phaselistener,Jpa,Jsf 2,Cdi,Named,Phaselistener,我们正在使用JBoss7.1、MySQL/PostgreSQL DB、JSF2.0和CDIBeans 我必须通过登录和密码实现基于DB的身份验证。我们有一个管理(行政)门户。当客户端在未登录的情况下打开受限页面时,如果客户端未登录,则应将请求重定向到login.*page 我尝试使用PhaseListener来实现这一点。 我可以登录和注销,但当我尝试打开另一个页面时,我遇到了一个问题: 我无法在PhaseListener类中获取@Named(“user”)公共类UserManagerbean。

我们正在使用JBoss7.1、MySQL/PostgreSQL DB、JSF2.0和CDIBeans

我必须通过登录和密码实现基于DB的身份验证。我们有一个管理(行政)门户。当客户端在未登录的情况下打开受限页面时,如果客户端未登录,则应将请求重定向到
login.*
page

我尝试使用
PhaseListener
来实现这一点。 我可以登录和注销,但当我尝试打开另一个页面时,我遇到了一个问题: 我无法在
PhaseListener
类中获取
@Named(“user”)公共类UserManager
bean。我试图通过使用
FacesContext
,&EL…,来获得它,但这一切都帮不了我

UserManager
验证登录并将登录的用户存储为
current
属性。在每个请求中,如果
{user.current}
不是
null
,我想检查
PhaseListener
。但是我无法在
PhaseListener
中获取
{user}
bean

public BeanManager getBeanManager() {
    BeanManager beanManager = null;
    try {
        InitialContext initialContext = new InitialContext();
        beanManager = (BeanManager) initialContext.lookup("java:comp/BeanManager");
    } catch (NamingException e) {
        logger.log(Level.SEVERE, "Couldn't get BeanManager through JNDI", e);
    }
    return beanManager;
}

public <T> T getBean(final Class<T> clazz) {
    BeanManager bm = getBeanManager();
    Bean<T> bean = (Bean<T>) bm.getBeans(clazz).iterator().next();
    CreationalContext<T> ctx = bm.createCreationalContext(bean);
    return (T) bm.getReference(bean, clazz, ctx);
}
如何在
beforePhase()
afterPhase()
中获取名为
@的
>bean


更新:以下是我迄今为止的尝试:

private boolean loggedIn( FacesContext context ) throws IOException, ServletException
{
    LOGSTORE.debug( "loggedIn().2 " );

    HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
    HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();

//  ELContext elContext = FacesContext.getCurrentInstance().getELContext();
//  UserManager userManager = (UserManager) FacesContext.getCurrentInstance().getApplication()
//      .getELResolver().getValue( elContext, null, "user" );

    HttpSession session = (HttpSession) context.getExternalContext().getSession( true );
    UserManager userManager = (UserManager) session.getAttribute( "user" );

//  UserManager userManager = (UserManager) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get( "user" );

    if (!StringUtils.contains( ((HttpServletRequest) context.getExternalContext().getRequest())
        .getRequestURL().toString(), URL_SESSION_EXPIRED ))
    {

        if (userManager == null || !userManager.isLoggedIn())
        {
            LOGSTORE.debug( " userManager is " + (userManager == null ? "" : "not ") + " null" );
            if (userManager != null)
            {
                LOGSTORE.debug( " userManager.isLoggedIn() is "
                    + (userManager.isLoggedIn() ? "TRUE" : "FALSE") );
            }
            LOGSTORE.debug( " doPhaseFilter() - START REDIRECT " );
            response.sendRedirect( request.getContextPath() + "/" + homepage + "?auth-failed" );
        }
        return false;

    } else
    {
        LOGSTORE.debug( "loggedIn().3 it is " + homepage );
        return true;
    }
}

会话范围的CDI托管bean在HTTP会话中的存储方式与普通会话范围的JSF托管bean不同。会话范围内的JSF管理实际上是通过bean名称作为键存储在会话中的。然而,会话范围的CDI托管bean通过会话范围中的另一个映射被进一步抽象

您需要通过编程方式计算EL来获得它,而不是从会话映射中获取它。您的EL解析器尝试有一个错误,该值不包含任何
{}
表达式

ELContext elContext = FacesContext.getCurrentInstance().getELContext();
UserManager userManager = (UserManager) FacesContext.getCurrentInstance().getApplication()
    .getELResolver().getValue(elContext, null, "user");
相应地进行修正:

ELContext elContext = FacesContext.getCurrentInstance().getELContext();
UserManager userManager = (UserManager) FacesContext.getCurrentInstance().getApplication()
    .getELResolver().getValue(elContext, null, "#{user}");
顺便说一句,上面的缩写是
应用程序#evaluateExpressionGet()


请注意,
FacesContext上下文也已作为方法参数存在。

会话范围的CDI托管bean在HTTP会话中的存储方式与正常会话范围的JSF托管bean不同。会话范围内的JSF管理实际上是通过bean名称作为键存储在会话中的。然而,会话范围的CDI托管bean通过会话范围中的另一个映射被进一步抽象

您需要通过编程方式计算EL来获得它,而不是从会话映射中获取它。您的EL解析器尝试有一个错误,该值不包含任何
{}
表达式

ELContext elContext = FacesContext.getCurrentInstance().getELContext();
UserManager userManager = (UserManager) FacesContext.getCurrentInstance().getApplication()
    .getELResolver().getValue(elContext, null, "user");
相应地进行修正:

ELContext elContext = FacesContext.getCurrentInstance().getELContext();
UserManager userManager = (UserManager) FacesContext.getCurrentInstance().getApplication()
    .getELResolver().getValue(elContext, null, "#{user}");
顺便说一句,上面的缩写是
应用程序#evaluateExpressionGet()


请注意,
FacesContext上下文也作为方法参数存在。

希望这在下一版本的JSF中得到修复,该版本具有真正的CDI集成。您需要做的(并保持可移植性)是通过JNDI查找BeanManager,然后从BeanManager获取命名bean。

希望这在下一版本的JSF中得到修复,该版本具有真正的CDI集成。您需要做的(并保持可移植性)是通过JNDI查找BeanManager,然后从BeanManager获取命名bean。

另一个可能性是使用。它是一个便携式CDI扩展,允许您进行观察。

另一个可能性是使用。它是一个可移植的CDI扩展,允许您观察。

我使用以下代码从
PhaseListener
内部获取对CDI bean的引用

public BeanManager getBeanManager() {
    BeanManager beanManager = null;
    try {
        InitialContext initialContext = new InitialContext();
        beanManager = (BeanManager) initialContext.lookup("java:comp/BeanManager");
    } catch (NamingException e) {
        logger.log(Level.SEVERE, "Couldn't get BeanManager through JNDI", e);
    }
    return beanManager;
}

public <T> T getBean(final Class<T> clazz) {
    BeanManager bm = getBeanManager();
    Bean<T> bean = (Bean<T>) bm.getBeans(clazz).iterator().next();
    CreationalContext<T> ctx = bm.createCreationalContext(bean);
    return (T) bm.getReference(bean, clazz, ctx);
}

本例中的bean是一个
@依赖的
bean,它正在
PhaseListener
中使用我使用以下代码从
PhaseListener
中获取对CDI bean的引用

public BeanManager getBeanManager() {
    BeanManager beanManager = null;
    try {
        InitialContext initialContext = new InitialContext();
        beanManager = (BeanManager) initialContext.lookup("java:comp/BeanManager");
    } catch (NamingException e) {
        logger.log(Level.SEVERE, "Couldn't get BeanManager through JNDI", e);
    }
    return beanManager;
}

public <T> T getBean(final Class<T> clazz) {
    BeanManager bm = getBeanManager();
    Bean<T> bean = (Bean<T>) bm.getBeans(clazz).iterator().next();
    CreationalContext<T> ctx = bm.createCreationalContext(bean);
    return (T) bm.getReference(bean, clazz, ctx);
}

本例中的bean是一个
@Dependent
bean,正在
PhaseListener

中使用。请显示当您说“我试图使用FacesContext获得它,&EL…,这一切对我都没有帮助”时您尝试的代码我在上面添加了一个代码段——我试图在SessionPhaseListenerPlease中获取bean,请显示您在说“我试图使用FacesContext获取bean,&EL…,这对我没有帮助”时尝试的代码。我在上面添加了一个代码段——我试图在SessionPhaseListenerFunderful中获取bean!我尝试了各种各样的东西,但都是徒劳的,只有这个例子。现在我可以睡觉了!再次感谢巴卢斯克,太好了!我尝试了各种各样的东西,但都是徒劳的,只有这个例子。现在我可以睡觉了!再次感谢巴卢斯克。
public BeanManager getBeanManager() {
    BeanManager beanManager = null;
    try {
        InitialContext initialContext = new InitialContext();
        beanManager = (BeanManager) initialContext.lookup("java:comp/BeanManager");
    } catch (NamingException e) {
        logger.log(Level.SEVERE, "Couldn't get BeanManager through JNDI", e);
    }
    return beanManager;
}

public <T> T getBean(final Class<T> clazz) {
    BeanManager bm = getBeanManager();
    Bean<T> bean = (Bean<T>) bm.getBeans(clazz).iterator().next();
    CreationalContext<T> ctx = bm.createCreationalContext(bean);
    return (T) bm.getReference(bean, clazz, ctx);
}