@SessionScoped public class User {
... //settings, attributes, etc
}
@ViewScoped public class FooController {
@ManagedProperty(value="#{user}")
private User user;
...
}
@RequestScoped public class LoginController {
@ManagedProperty(value="#{user}")
private User user;
public String login() {
//handle Servlet 3.0 based authenticate()... if success, make new User object and slap it into context
request.getSession().setAttribute("user", user);
return "?faces-redirect=true";
}
...
}
xhtml页面几乎包含每个页面的登录控件。理想的情况是他们能够登录,页面将刷新,现有的FooController
将引用当前登录的用户,这有条件地呈现按钮/元素。行为是登录发生,但FooController
视图仍然是“有效”,因此永远不会尝试再次注入托管bean。如果我离开页面,然后返回到它[重建视图范围的bean],用户bean将被很好地重新注入...但我不希望有那个临时步骤。有什么想法吗?
我尝试了各种形式的FacesContext.getCurrentInstance().getViewRoot().getViewMap().remove("user");
,希望它会从会话中重新拉出来,但无济于事。我不想在我的LoginController中紧密耦合代码来引用特定的FooController或BarController或其他任何引用用户bean的函数。
答案 0 :(得分:0)
您为什么要从user
(当前会话中的@SessionBean
个对象的地图)中删除viewMap
(@ViewScoped
)?
您应该从FooController
删除@ViewScoped
,viewMap
,即
FacesContext.getCurrentInstance().getViewRoot().getViewMap().remove("fooController");.
这就是摆脱了viewscoped bean并强制创建一个新bean。当然,无论如何你都需要刷新页面。
如果你打算删除会话bean,你应该直接访问会话:
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("user");.
摆脱了用户对象
答案 1 :(得分:0)
好的,我在驱动器上找到了这个,这是一个生命周期问题。我试图让JSF做一些它不应该对托管bean做的事情。
我没有新建一个User
对象并将其重新分配给user
中LoginController
的托管实例,而是将登录方法更改为:
public String login() {
//handle Servlet 3.0 based authenticate()... if success...
User loadedFromDB = someDao.load(principal.getName());
user.setDefaultPage(loadedFromDB.getDefaultPage()); // NOTE: The user object IS THE MANAGED BEAN
user.setDefaultScheme(loadedFromDB.getDefaultScheme()); // This is the same object the view scoped bean has a ref on, so directly setting that object's fields proliferates that to any other bean that has the user in scope.
... //etc... not calling NEW, not reassigning object ref to user
loadedFromDB = null;
return "?faces-redirect=true";
}
这实现了所需要的。谁知道,如果你停止与框架战斗一分钟并且只是使用它,它可以帮助你:)