@Inject annotation for an object and two different behaviors of this object

I am using JSF 2.2 and CDI. I created an example below to show you the essence of my problem. You can see below:

  • two pages xhtml,
  • Session CDI bean ( LoginController ), which is the controller for xhtml page1,
  • the watched CDI bean ( DataController ), which is the controller for xhtml page2,
  • the requested CDI bean ( DataServiceImpl ), which is a service for the DataController bean.

This is a use case and a data stream:

xhtml page2 -> DataController controller -> call dataService.addData() in the send() method (which is in the DataController class) -> execute addData() (which is in the DataServiceImpl class)

The heart of my problem:

  • If I insert a LoginController into the DataServiceImpl class, the LoginController object LoginController not work (ie returns null ) [option 1 in the code below].
  • If I insert a LoginController into the DataController class, the LoginController object works fine (ie, returns what I want) [Option 2 in the code below].

My question is: why does this injected object behave in two different ways depending on the injection site?

This is part of my xhtml page1:

 <h:form> <p:growl id="growl" showDetail="false" /> <h:inputText id="username" value="#{userLogin.username}" label="Username" required="true" requiredMessage="Username: This field is required." title="Enter your username." pt:placeholder="Username" /> <h:inputSecret id="password" value="#{userLogin.password}" label="Password" required="true" requiredMessage="Password: This field is required." title="Enter your password." pt:placeholder="Password" /> <p:commandButton value="Login" action="#{loginController.login}" update="growl" /> </h:form> 

This is part of my xhtml page2:

 <h:form> <p:growl id="growl" showDetail="false" /> <p:panelGrid id="panel" columns="2" styleClass="ui-noborder" columnClasses="rightalign,leftalign"> <p:outputLabel for="data" value="Data:" /> <p:inputText id="data" value="#{data.text}" required="true" requiredMessage="Data: This field is required." /> <p:commandButton id="buttonSend" value="Send" action="#{dataController.send()}" update="messages" /> </p:panelGrid> </h:form> 

This is a session limited CDI bean:

 @Named @SessionScoped public class LoginController implements Serializable { private static final long serialVersionUID = -6322113716363932422L; public String login(){ if(userService.login(userLogin)){ currentUser=userService.getCurrnetUser(userLogin.getUsername()); return "home?faces-redirect=true"; } else{ facesContext.addMessage(null, new FacesMessage("Data entered are incorrect")); return null; } } public String logout(){ currentUser=null; return "login?faces-redirect=true"; } public boolean isLoggedIn() { return currentUser!=null; } @Produces @LoggedIn public UserAccount getCurrentUser(){ return currentUser; } @Inject private FacesContext facesContext; @Inject private UserServiceImpl userService; @Named @Produces @RequestScoped private UserAccount userLogin=new UserAccount(); private UserAccount currentUser; } 

This kind of CDI bean:

 @Named @ViewScoped public class DataController implements Serializable { private static final long serialVersionUID = 1383572529241805730L; public void send(){ /* OPTION 2 * If I inject the LoginController here * instead of in DataServiceImpl bean, the loginController object * works fine (ie it isn't null and returns the name of the user). */ String name=loginController.getCurrentUser().getName(); dataService=new DataServiceImpl(); dataService.addData(data.getText); } @Named @Produces @RequestScoped private Data data=new Data(); @Inject private DataService dataService; @Inject private LoginController loginController; } 

This is the CDI bean identifier with the request:

 @Named @RequestScoped public class DataServiceImpl implements DataService { @Override public void addData(String data) { /* OPTION 1 * If I inject the LoginController here * instead of DataController bean, the loginController object * doesn't work (ie returns null. I get the NullPointerException exception * in line below due to the loginController object which is null) */ String name=loginController.getCurrentUser().getName(); //Proccess some data } @Inject private LoginController loginController; } 
0
source share
1 answer

I really do not understand your design, and this may be part of the problem.

You should not enter the controller in another controller or enter the controller in the service.

Seeing that your LoginController creates @LoggedIn UserAccount , why not just enter this instead of entering LoginController and calling loginController.getCurrentUser().getName() ?

0
source

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


All Articles