@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 pages include the login controls on pretty much every page. The ideal would be that they are able to login, and the page will refresh and the existing FooController
would have the reference to the currently logged in user, which conditionally renders buttons / elements. The behavior is that the login occurs, but the FooController
view is still "valid", so the managed bean never is attempted to be injected again. If I navigate off the page, and back onto it [reconstructing the view scoped bean] the user bean is reinjected nicely... but I'd prefer not to have that interim step. Any ideas?
I've tried various forms of FacesContext.getCurrentInstance().getViewRoot().getViewMap().remove("user");
in hopes that it will re-pull it from session but no avail. I do not want to tightly couple code in my LoginController to reference specifically invalidating a FooController or BarController or any other that refs the user bean.
Ok, I figured this out on the drive home, it was a lifecycle problem. I was trying to get JSF to do something it shouldn't be doing to managed beans.
Instead of new'ing up a User
object and reassigning it to the managed instance of user
in LoginController
, i changed the login method to look like this:
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";
}
This accomplishes what was needed. Who knew, if you stop fighting the framework for a minute and just use it, it helps you out :)