How to retrieve a session scoped managed bean in a PhaseListener?

血红的双手。 提交于 2019-12-11 07:35:29

问题


I'm having troubles in setting an Authorization Listener (that implements PhaseListener) to manage authentication and autorization.

More specifically, I set a session scoped bean called SessionBean:

@ManagedBean
@SessionScoped
public class SessionBean{

   private String loggedUser;

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

And in my 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>

In login() I make controls on username/password and if successful I set "loggedUser".

My AuthorizationListener is:

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 {
                 ...
            }
    }

    ...
}

And in the 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 -->

But I receive a null pointe sessionBean.getLoggedUser(). So, the SessionBean is still not created when the AuthorizationListener check the user. This is why I added a "if SessionBean doesn't exists, create it and put it in SessionMap", but still not working.

I'm not forced to use this approach for authentication and authorization, but what I need is to avoid "session.setAttribute("username", username). So any other strategy would be really apreciated. Thanks, Andrea

EDIT: as BalusC suggested, I edited the afterPhase method. Still having troubles with always null SessionBean.


回答1:


The @ManagedProperty works in @ManagedBean classes only. Your PhaseListener isn't.

You need to manually get it from the session map.

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

Note that it can be still null on the very first HTTP request.

The common approach, however, is to use a servlet Filter for the job, not a PhaseListener. The session scoped managed bean is available as a session attribute.

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



回答2:


Here in your code, in your phaseListener, you did not tell in which Phase exactly you would implement the code and you should call your managed bean. You should do this in RESTORE_VIEW Phase in AuthorizationListener override method getPhaseId(). See the following:

public PhaseId getPhaseId() {

        return PhaseId.RESTORE_VIEW;

    }

If your managed bean is still null, remove managed bean annotations, register it in faces_config, and use this helper method in phase listener to call the managed bean:

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

To call it in after phase method, use:

public void afterPhase(PhaseEvent event) {

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


来源:https://stackoverflow.com/questions/12438869/how-to-retrieve-a-session-scoped-managed-bean-in-a-phaselistener

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!