如何检索在的PhaseListener范围的托管bean会话?(How to retrieve a

2019-10-17 05:35发布

我有在设定的授权侦听器(实现的PhaseListener)来管理认证和autorization烦恼。

更具体地说,我设置会话范围的bean称为会话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>

在登录()我就用户名/密码控制,如果成功我设置“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 -->

但是我收到一个空足尖sessionBean.getLoggedUser()。 所以,当AuthorizationListener检查用户仍不能创建会话Bean。 这就是为什么我添加了一个“如果会话Bean不存在,创建它,并把它放在SessionMap”,但仍然没有工作。

我不是被迫使用这种方法进行身份验证和授权,但我需要的是避免“session.setAttribute(”用户名”,用户名)。因此,任何其他的策略将是非常apreciated。谢谢你,安德烈

编辑:作为BalusC建议,我编辑的afterPhase方法。 仍然有总是空SessionBean的烦恼。

Answer 1:

@ManagedProperty工作在@ManagedBean只有类。 您PhaseListener是没有的。

你需要从会话映射到手动得到它。

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

需要注意的是它可以仍然null的第一个HTTP请求。

常见的方法,然而,就是使用servlet Filter的工作,而不是一个PhaseListener 。 会话范围的托管bean是作为一个会话属性。

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


Answer 2:

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

public PhaseId getPhaseId() {

        return PhaseId.RESTORE_VIEW;

    }

如果您的托管bean仍然是空,除去托管bean注释,在注册它faces_config ,并使用此helper方法相监听器调用托管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();      


文章来源: How to retrieve a session scoped managed bean in a PhaseListener?