2010-11-19 7 views
3

Ich habe eine Managed Bean LoginBean:Managed Bean ist manchmal null und manchmal nicht

@ManagedBean(name = "loginBean") 
@SessionScoped 
public class LoginBean implements Serializable { 

    private String email, password; 
    private BasicUser user; 

    /** Creates a new instance of LoginBean */ 
    public LoginBean() { 
    } 

    public void setUser(BasicUser user) { 
     this.user = user; 
    } 

    public BasicUser getUser() { 
     return user; 
    } 

    ... 
} 

Und dann eine Phaselistener, der die Sitzungen loginBean bekommt.

public class FacebookSignInListener implements PhaseListener, UserService { 
private LoginBean bean;  
.... 

    @Override 
    public PhaseId getPhaseId() { 
     return PhaseId.RENDER_RESPONSE; 
    } 

    @Override 
    public void afterPhase(PhaseEvent event) { 
    HttpSession session = (HttpSession) event.getFacesContext().getExternalContext().getSession(true); 
    bean = (LoginBean) session.getAttribute("loginBean"); 
    bean.setUser(facebookUser); 
} 
    @Override 
    public void beforePhase(PhaseEvent event) { 
    FacesContext fc = FacesContext.getCurrentInstance(); 
    request = (HttpServletRequest) fc.getExternalContext().getRequest(); 
    boolean isLoginPage = 
      (fc.getViewRoot().getViewId().indexOf("welcome") > -1); 
    if (isLoginPage) { 
     try { 
      FBOauth fbo = new FBOauth(this); 
      fbo.doLogin(request); 
     } catch (IOException ex) { 
      Logger.getLogger(FacebookSignInListener.class.getName()).log(Level.SEVERE, "Could not exchange code for access_token. Page where not found.", ex); 
     } 
    } 
} 

    @Override 
    public boolean authFacebookLogin(String accessToken, FacesContext fc) throws FacebookException { 
     if (accessToken != null) { 
      FacebookClient facebookClient = new DefaultFacebookClient(accessToken); 
      User fbUser = facebookClient.fetchObject("me", User.class); 

      UserHelper uh = new UserHelper(); 
      FacebookUser facebookUser = (FacebookUser) uh.getByFacebookId(fbUser.getId());   
// Does the user already exist and is he already connected with facebook. 
      if (facebookUser != null) {    
       return true; 
      } 
     } 
     } 
} 

Als ich nach dem Einschalten der Presse-Launch Anwendung Admin-Konsole bereitstellen, Protokolle in meine Anwendung über Facebook gibt es kein Problem mit dem Code unten. Ich kann mich wieder abmelden und einloggen und immer noch kein Problem. Wenn ich dann Browser ändern und versucht, über facebook einzuloggen hier bekomme ich eine Nullpointer wo ich

bean.setUser (facebookUser)

Dies geschieht auch, wenn ich das erste Browser zu schließen, öffnet sich wieder und versucht sich über Facebook anzumelden. Warum passiert dies?

Ich benutze Glassfish v3.

Antwort

4

Wenn die Sitzungsbereichs-Bean null ist, bedeutet das einfach, dass sie noch nicht für die Sitzung erstellt wurde. Dies kann während der ersten Anfrage einer neuen Sitzung geschehen. Sie müssen es selbst erstellen und selbst in den Sitzungsumfang aufnehmen. JSF wird es einfach im Rest der Sitzung wiederverwenden.

Ihre Art, die Session-Bean zu packen, ist ein bisschen ungeschickt. Sie erhalten die rohe Servlet-API unter den JSF-Hauben. Sie können auch ExternalContext#getSessionMap() verwenden, um die Sitzungsattribute zu verwalten.

Map<String, Object> sessionMap = externalContext.getSessionMap(); 
LoginBean loginBean = (LoginBean) sessionMap.get("loginBean"); 
if (loginBean == null) { 
    loginBean = new LoginBean(); 
    sessionMap.put("loginBean", loginBean); 
} 
// ... 

Beachten Sie, dass Sie sollten die Bohne als Instanzvariable der PhaseListener nicht erklären. Es gibt nämlich eine einzige PhaseListener Instanz während der gesamten Lebensdauer der Anwendung, so dass alle Instanzvariablen unter allen Anfragen/Sitzungen geteilt werden. Mit anderen Worten: es ist nicht threadsicher.

2

Scheint so, als ob Sie versuchen, die Bean zu benutzen, bevor sie erstellt wurde, seit Ihr PhaseListener in der ersten Phase feuert. Haben Sie versucht, es in eine spätere Phase zu verschieben?

Edit: Sie greifen auf die Sitzung mit der Flagge Kiste auf true gesetzt:

HttpSession session = (HttpSession) externalContext.getSession(true); 

So Ihre neu gewohnt erstellte Sitzung schließen jede Session Beans scoped. Das Framework instanziiert die sitzungsspezifische Bean und fügt das Sitzungsobjekt ein, wenn ein Ausdruck ausgewertet wird, der auf die Bean verweist, was hier nicht der Fall ist.

+2

Das boolesche Flag erzwingt keine Aktualisierung der Sitzung. Es weist den Servletcontainer an, einen neuen zu erstellen, wenn er nicht bereits existiert. Die Ursache liegt in der Tat in einer zu frühen Phase (wenn die Bohne noch nicht erstellt wurde) wie in Ihrem ersten Satz. – BalusC

+0

Richtig, aber für den Fall, dass es keine aktive Sitzung gibt, wird eine neue Sitzung erstellt. In diesem Fall wird die Session-Bean nicht verfügbar sein. Oder verpasse ich hier etwas? ;-) – tasel

+1

Ihre Antwort besagt, dass dies dadurch verursacht wird, dass das create Flag auf true gesetzt wird. Das ist falsch. – BalusC

Verwandte Themen