(this was originally published at https://stackoverflow.com/questions/10691324/working-with-3-java-beans-controller-backing-model , but the OP removed the question and I did not want to discard the answer, I think the repost on also suitable for this issue)
You probably paid too much attention to this block of ICEfaces , which contains mostly nonsense .
You should have one JSF managed bean that acts as a controller, you already have it: UserController
. You should have a simple bean that represents the model you already have: UserVO
. You must have a bean enterprise that represents the service, you already have: UserBO
. The last two do not need to manage JSF beans.
Based on the background of the issue, you are using Glassfish, so you can use JPA and EJB. Thus, the model class must be @Entity
JPA, and the service class must be @Stateless
EJB.
However, the use case of the "login user" is special. You do not want the entity to be managed through a bean session, or it would be implicitly created by JSF. You'd better put it right in the session area yourself, so you can check #{not empty user}
if the user is logged in or not.
Everything with everyone should look something like this:
@Entity public class User { private String username; private String password;
@Stateless public class UserService { @PersistenceContext private EntityManager em; public User find(String username, String password) { return em.createQuery("SELECT u FROM User u WHERE username = :username AND password = MD5(:password)", User.class) .setParameter("username", username) .setParameter("password", password) .getSingleResult(); } }
@ManagedBean @ViewScoped public class UserController { private String username; private String password; @EJB private UserService service; public String login() { FacesContext context = FacesContext.getCurrentInstance(); try { User user = userService.find(username, password); context.getExternalContext().getSessionMap().put("user", user); return "/views/commons/home.html?faces-redirect=true"; } catch (NoResultException) { context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Unknown login, please try again", null)); return null; } } public String logout() { FacesContext.getCurrentInstance().getExternalContext().invalidateSession(); return "/views/commons/login.html?faces-redirect=true"; }
from
<h:form> <h:inputText value="#{userController.username}" required="true" /> <h:inputSecret value="#{userController.password}" required="true" /> <h:commandButton value="login" action="#{userController.login}"/> <h:messages /> </h:form>
Alternatively, you can make UserController
session bean that contains the User
object, you will need to add an additional method to check if the user is registered or not so that you can use it in EL with #{userController.loggedIn}
.
@ManagedBean @SessionScoped public class UserController { private User user = new User(); @EJB private UserService service; public String login() { FacesContext context = FacesContext.getCurrentInstance(); try { user = userService.find(user.getUsername(), user.getPassword()); return "/views/commons/home.html?faces-redirect=true"; } catch (NoResultException) { context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Unknown login, please try again", null)); return null; } } public String logout() { FacesContext.getCurrentInstance().getExternalContext().invalidateSession(); return "/views/commons/login.html?faces-redirect=true"; } public boolean isLoggedIn() { return user.getId() != null; }
from
<h:form> <h:inputText value="#{userController.user.username}" required="true" /> <h:inputSecret value="#{userController.user.password}" required="true" /> <h:commandButton value="login" action="#{userController.login}"/> <h:messages /> </h:form>