首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在PhaseListener中访问@Named bean?

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

Stack Overflow用户
提问于 2012-01-23 16:39:35
回答 4查看 4K关注 0票数 1

我们使用的是JBoss 7.1、MySQL/PostgreSQL、JSF2.0和CDI。

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

我试图通过使用PhaseListener来做到这一点。我可以登录和注销,但是当我试图打开另一个页面时,我遇到了一个问题:我无法在@Named("user") public class UserManager类中获得PhaseListener bean。我试图通过使用FacesContext &EL.来获得它,这一切对我都没有帮助。

UserManager验证登录并将登录用户存储为current属性。对于每个请求,如果PhaseListener不是null,我想签入#{user.current}。但是我不能把#{user}豆放在PhaseListener里。

我怎样才能在beforePhase()afterPhase()中得到一个beforePhase() bean?

更新:到目前为止,我的尝试如下:

代码语言:javascript
复制
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;
    }
}
EN

回答 4

Stack Overflow用户

发布于 2012-01-24 14:35:12

会话范围内的CDI托管bean不像正常会话范围内的JSF托管bean那样存储在HTTP会话中。会话范围内的JSF托管确实是以bean名称作为密钥存储在会话中的。但是,会话范围内的CDI托管bean将通过会话范围中的另一个映射进行更远的抽象。

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

代码语言:javascript
复制
ELContext elContext = FacesContext.getCurrentInstance().getELContext();
UserManager userManager = (UserManager) FacesContext.getCurrentInstance().getApplication()
    .getELResolver().getValue(elContext, null, "user");

相应地,修正如下:

代码语言:javascript
复制
ELContext elContext = FacesContext.getCurrentInstance().getELContext();
UserManager userManager = (UserManager) FacesContext.getCurrentInstance().getApplication()
    .getELResolver().getValue(elContext, null, "#{user}");

顺便说一句,上面的缩写是Application#evaluateExpressionGet()

代码语言:javascript
复制
UserManager userManager = context.getApplication()
    .evaluateExpressionGet(context, "#{user}", UserManager.class);

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

票数 7
EN

Stack Overflow用户

发布于 2012-12-20 19:56:39

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

代码语言:javascript
复制
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,您可以如下所示。

代码语言:javascript
复制
DataManager dataManager = getBean(DataManager.class);

本例中的bean是一个@Dependent bean,它正在PhaseListener中使用。

票数 2
EN

Stack Overflow用户

发布于 2012-01-24 19:34:05

希望这个问题在JSF的下一个版本中得到了修正,它为这类东西提供了真正的CDI集成。您需要做的(并维护可移植性)是通过JNDI查找BeanManager,然后从BeanManager中获取命名bean。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8975154

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档