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(){ 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) { String name=loginController.getCurrentUser().getName();
source share