2013-11-26 21 views
0
@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很好地重新注入...但我不希望有这个临时步骤。有任何想法吗?更新视图范围的JSF beans的注入bean

我试过各种形式的FacesContext.getCurrentInstance().getViewRoot().getViewMap().remove("user");,希望它能重新从会话中拉出来,但无济于事。我不想在我的LoginController中紧密耦合代码,以引用特定的FooController或BarController或任何其他引用用户bean的无效代码。

回答

0

好吧,我想通了这一点上开车回家,这是一个生命周期问题。我试图让JSF做一些它不应该对托管bean做的事情。

相反new'ing了User对象和LoginController重新分配给的user的管理实例的,我改变了登录的方法是这样的:

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

这完成需要的是什么。谁知道,如果你停止与框架战斗一分钟,只是使用它,它可以帮助你:)

0

为什么要从viewMap(当前会话中的@ViewScoped对象的地图)中删除user(a @SessionBean)?

你应该删除FooController@ViewScoped,从viewMap豆,即

FacesContext.getCurrentInstance().getViewRoot().getViewMap().remove("fooControl‌​ler");. 

这是将摆脱viewscoped豆和强制要创建一个新的。当然,无论如何你都需要刷新页面。

如果你在去除但会话bean的意图,你应该直接访问会话:

FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("user");. 

这摆脱了用户对象

+0

那么,目标不是要删除用户bean,而是扩大更新的用户对象到任何视图范围的bean。我测试了你的解决方案,它可以工作,但是'FooController'只是大约20个视图范围的bean中的一个,它们可能处于活动状态,这取决于用户登录的页面。 [登录表单是一个弹出式面板,几乎包含在每个页面上]。这似乎是一个纠缠问题,让LoginController的代码名称为20+ beans试图删除。 – Eric

相关问题