更新视图范围的JSF bean的注入bean

时间:2013-11-26 21:00:18

标签: jsf jsf-2 view-scope managed-property

@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的函数。

2 个答案:

答案 0 :(得分:0)

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

您应该从FooController删除@ViewScopedviewMap,即

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

这就是摆脱了viewscoped bean并强制创建一个新bean。当然,无论如何你都需要刷新页面。

如果你打算删除会话bean,你应该直接访问会话:

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

摆脱了用户对象

答案 1 :(得分:0)

好的,我在驱动器上找到了这个,这是一个生命周期问题。我试图让JSF做一些它不应该对托管bean做的事情。

我没有新建一个User对象并将其重新分配给userLoginController的托管实例,而是将登录方法更改为:

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

这实现了所需要的。谁知道,如果你停止与框架战斗一分钟并且只是使用它,它可以帮助你:)