托管Bean有时为null,有时不为null [英] Managed bean is sometimes null and sometimes not

查看:86
本文介绍了托管Bean有时为null,有时不为null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个托管bean LoginBean:

I have a managed bean LoginBean:

@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;
    }

   ...
 }

然后是获取会话loginBean的PhaseListener.

And then a PhaseListener who gets the sessions loginBean.

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;
            }
         }
      }
}

当我在管理控制台上部署后按启动应用程序时,通过Facebook登录到我的应用程序时,以下代码没有问题.我可以注销并再次登录,仍然没有问题.如果我随后更改浏览器并尝试通过Facebook登录,则会在此获取NullPointerException

When I after deploy on the admin console press launch application, logs into my application via facebook there is no problem with the code below. I can logout and log in again and still no problem. If I then change browser and tries to login via facebook here I get a NullPointerException where I do

bean.setUser(facebookUser)

bean.setUser(facebookUser)

如果我关闭第一个浏览器,再次打开并尝试通过Facebook登录,也会发生这种情况.为什么会这样?

This also happens if I close the first browser, opens again and tries to login via facebook. Why is this happening?

我正在使用Glassfish v3.

I am using Glassfish v3.

推荐答案

如果会话作用域bean是null,则仅表示尚未为该会话创建它.这可能是在新会话的第一个请求期间发生的.您必须自己创建它,然后自己将其放入会话范围. JSF只会在会话的剩余时间内重用它.

If the session scoped bean is null then it simply means that it hasn't been created for the session yet. This can happen during the very first request of a fresh session. You've to create it yourself and put it in the session scope yourself. JSF will just reuse it in the remnant of the session.

您获取会话作用域bean的方法有些笨拙.您可以从JSF的幕后获得原始的Servlet API.您也可以只使用 ExternalContext#getSessionMap() 管理会话属性.

Your way of grabbing the session scoped bean is a bit clumsy. You're getting the raw Servlet API from under the JSF's hoods. You could also just use ExternalContext#getSessionMap() to manage the session attributes.

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

请注意,您不应将bean声明为PhaseListener的实例变量.在应用程序的整个生命周期中只有一个PhaseListener实例,因此所有实例变量将在所有请求/会话之间共享.换句话说:它不是线程安全的.

Note that you shouldn't declare the bean as an instance variable of the PhaseListener. There is namely a single PhaseListener instance throughout the application's lifetime, so all instance variables would be shared among all requests/sessions. In other words: it's not threadsafe.

这篇关于托管Bean有时为null,有时不为null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆