繁体   English   中英

如何在PhaseListener中检索会话范围的托管bean?

[英]How to retrieve a session scoped managed bean in a PhaseListener?

我在设置授权监听器(实现PhaseListener)以管理身份验证和自动化方面遇到了麻烦。

更具体地说,我设置了一个名为SessionBean的会话范围bean:

@ManagedBean
@SessionScoped
public class SessionBean{

   private String loggedUser;

   public SessionBean(){
    logger.info("Sono nel costruttore di SessionBean()");
   }
   public String login(){
       ....
   }
   ...
}

在我的sun-web.xml中:

  <managed-bean>
    <managed-bean-name>SessionBean</managed-bean-name>
    <managed-bean-class>it.uniroma3.acme.auction.bean.SessionBean</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
  </managed-bean>

在login()中,我对用户名/密码进行控制,如果成功,我设置“loggedUser”。

我的AuthorizationListener是:

public class AuthorizationListener implements PhaseListener {

    private String currentUser;

    private SessionBean sessionBean;

    public void afterPhase(PhaseEvent event) {
        SessionBean sessionBean = (SessionBean)event.getFacesContext().getExternalContext().getSessionMap().get("SessionBean");
        String currentUser = sessionBean.getLoggedUser();

        if (sessionBean != null) {
            ...
               String currentUser = sessionBean.getLoggedUser();
        }
            else {
                 ...
            }
    }

    ...
}

在sun-web.xml中:

 <!-- Authentication and authorization block starting -->
    <lifecycle>
        <phase-listener>AuthorizationListener</phase-listener>
    </lifecycle>
    <navigation-rule>
        <from-view-id>/*</from-view-id>
        <navigation-case>
            <from-outcome>loginPage</from-outcome>
            <to-view-id>login.jsf</to-view-id>
        </navigation-case>
    </navigation-rule>
  <!-- Authentication and authorization block ending -->

但我收到一个空的pointe sessionBean.getLoggedUser()。 因此,当AuthorizationListener检查用户时,仍未创建SessionBean。 这就是我添加“如果SessionBean不存在,创建它并将其放在SessionMap中”的原因,但仍然无效。

我不是被迫使用这种方法进行身份验证和授权,但我需要的是避免使用“session.setAttribute(”username“,username)。所以任何其他策略都会真的是apreciated。谢谢,Andrea

编辑:正如BalusC建议的那样,我编辑了afterPhase方法。 始终为null的SessionBean仍然存在问题。

@ManagedProperty仅适用于@ManagedBean类。 您的PhaseListener不是。

您需要从会话映射中手动获取它。

SessionBean sessionBean = (SessionBean) event.getFacesContext()
    .getExternalContext().getSessionMap().get("SessionBean");

请注意,它在第一个HTTP请求时仍可以为null

但是,常见的方法是为作业使用servlet Filter ,而不是使用PhaseListener 会话范围的托管bean可用作会话属性。

SessionBean sessionBean = (SessionBean) session.getAttribute("sessionBean");

在这里,你的代码,在你的PhaseListener,你知道在哪儿阶段正是你所执行的代码,你应该打电话给你的托管bean。 您应该在AuthorizationListener覆盖方法getPhaseId()中的RESTORE_VIEW阶段中执行此操作。 请参阅以下内容:

public PhaseId getPhaseId() {

        return PhaseId.RESTORE_VIEW;

    }

如果托管bean仍为null,则删除托管bean注释,在faces_config注册它,并在阶段侦听器中使用此帮助器方法来调用托管bean:

public static Object resolveExpression(String expression) {
    FacesContext ctx = FacesContext.getCurrentInstance();
    Application app = ctx.getApplication();
    ValueBinding bind = app.createValueBinding(expression);
    return bind.getValue(ctx);
}

要在阶段后方法中调用它,请使用:

public void afterPhase(PhaseEvent event) {

SessionBean sessionBean =(SessionBean)resolveExpression("#{SessionBean}");
String currentUser = sessionBean.getLoggedUser();      

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM