Access bean session from bean request area

I am trying to use the template found on the IceFaces page (I am not using IceFaces using PrimeFaces)

In this case, I have two beans:

UserController and Usermodel

In my UserModel, I have an instance of UserVO (created by another programmer). In my UserController, I have the following:

@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 install it with what was returned from bo.executeLogin() , and it works, my object is returned.

To make sure the user is logged in, I have a property in 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 template.xhtml with:

 <ui:fragment rendered="#{userModel.loggedIn}"> <ui:include src="../includes/top.xhtml"/> </ui:fragment> 

And the fact is that it does not work, does not get the value of the loggedIn property.

I assume that to access this path, I kind of create a new instance of UserModel, if so, this is a problem because my UserController is not connected to the session, but only UserModel

EDIT

Instead of using this loggedIn property loggedIn I know that I can simply check if the UserModel userVo property is userVo , but the problem is with the bean session, I cannot access it with UserController, where it is because it is not a limited session, and my template.xhtml will be used by each page.

+4
source share
3 answers

Instead of creating a new UserModel instance in UserController , enter its @ManagedProperty .

In UserController :

 @ManagedProperty(value="#{userModel}") private UserModel model; // add getter and setter for userModel (important!) 

Then you do not need to create an instance in the constructor and will always receive an instance bound to the UserModel session in your controller.

UPDATE:

I think you complicate the login process with your rigorous MVC approach. In JSF, the boundaries between the model, view, and controller are somewhat blurry or overlap.

I recommend reading this interesting question and answers and especially this answer for more information on this topic.

As for your specific problem. I'm not quite sure what the reason is, but what you should avoid is creating an instance of a managed bean yourself and messing around with injected and self-initialized beans instances.

I would also recommend combining your beans into one bean. Then you have no problem with circular dependencies and null links.

+5
source

(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> 
+7
source

You can use dependency injection to get values ​​from this bean with a session scope.

 @Inject UserModel user; 

Then you can use this object in your UserControl bean. By the way, you do not need to implement serializable when you are dealing with RequestScope beans.

0
source

Source: https://habr.com/ru/post/1413244/


All Articles