I'm trying to use a pattern found on a IceFaces page.(I'm not using IceFaces, using PrimeFaces)
In this case I have two beans:
UserController and Usermodel
On my UserModel I have a instance of UserVO (created by another programmer). On My UserController I have this:
@ManagedBean
@RequestScoped
public class UserController implements Serializable
{
private static final long serialVersionUID = 1L;
private UserBO bo;
private UserModel model;
public UserController()
{
bo = new UserBO();
model = new UserModel();
}
public void Login() throws IOException
{
model.setUserVo(bo.executeLogin(model.getUserVo()));
ExternalContext externalContent = FacesContext.getCurrentInstance().getExternalContext();
if (!model.getUserVo().isError())
{
model.setLoggedIn(true);
externalContent.getSessionMap().put("userSession", model);
externalContent.redirect(externalContent.getRequestContextPath() + "/views/request/search.html");
} else
{
model.setLoggedIn(false);
FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, model.getUserVo().getMessage(), model.getUserVo().getLogin());
FacesContext.getCurrentInstance().addMessage(null, facesMessage);
}
}
public UserBO getBo()
{
return bo;
}
public void setBo(UserBO bo)
{
this.bo = bo;
}
public UserModel getModel()
{
return model;
}
public void setModel(UserModel model)
{
this.model = model;
}
}
As you can see, I create a new instance of UserModel and set it with what was returned from the bo.executeLogin()
and it is working, my object is returned.
To make sure the user is logged in, I have a property on my UserModel:
@ManagedBean
@SessionScoped
public class UserModel
{
private UserVO userVo;
private Boolean loggedIn = false;
public UserModel()
{
userVo = new UserVO();
}
public UserVO getUserVo()
{
return userVo;
}
public void setUserVo(UserVO userVo)
{
this.userVo = userVo;
}
public Boolean getLoggedIn()
{
return loggedIn;
}
public void setLoggedIn(Boolean loggedIn)
{
this.loggedIn = loggedIn;
}
I have a template.xhtml with:
<ui:fragment rendered="#{userModel.loggedIn}">
<ui:include src="../includes/top.xhtml"/>
</ui:fragment>
And the thing is that it is not working, is not getting the loggedIn
property value.
My guess is that accessing this way I'm kinda creating a new instance of UserModel, if so, it is a problem because my UserController is not session scoped, only the UserModel
EDIT
Instead of using this loggedIn
property I know I can simply check if the UserModel userVo
property is set but the problem is about the session scoped bean, I can't access it from UserController, where it is set because it isn't scoped session, and my template.xhtml will be used by every page.
Instead of creating a new
UserModel
instance in yourUserController
, inject it with@ManagedProperty
.In
UserController
:Then you don't have to instantiate it in the constructor and will always get the session scoped instance of
UserModel
in your controller.UPDATE:
I think you are complicating the login process with your strict MVC approach. In JSF the borderlines between model, view and controller are somewhat blurred or overlapping.
I recommend reading this interesting question and answers and especially this answer for more information on that topic.
As to your concrete problem. I am not quite sure what is the reason but what you should definitely avoid is to instantiate managed bean by youself and fiddle around with both injected and self-initialized instances of beans.
Also I would recommend to merge your beans together into a single bean. Then you don't have the problems with circular dependencies and null references.