托管Bean有时为null,有时不为null [英] Managed bean is sometimes null and sometimes not
问题描述
我有一个托管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屋!