Reputation: 55
Why CDI don't inject my backing bean (session scope) in this ActionListener? The loginBean instance is always null. I have the impression that CDI does not manage the listener instances : it's right?
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.inject.Inject;
public class CancelListener implements javax.faces.event.ActionListener {
private LoginBean loginBean;
@Inject
public void setLoginBean(LoginBean loginBean) {
this.loginBean = loginBean;
}
@Override
public void processAction( ActionEvent event ) throws AbortProcessingException {
loginBean.setLogin( "" );
loginBean.setPassword( "" );
}
}
Here the definition of my LoginBean class.
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.faces.event.ActionEvent;
import javax.inject.Named;
@Named
@SessionScoped
public class LoginBean implements Serializable {
private static final long serialVersionUID = -5433850275008415405L;
private String login = "[email protected]";
private String password = "007";
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
And my listener is connected to the button with this code :
<h:commandButton value="Cancel" immediate="true">
<f:actionListener type="mypackage.CancelListener" />
</h:commandButton>
I know that i can use a method directly on the backing bean (connected with actionListener tag attribute), but I would like to understand how to make my class compatible with CDI and how to force the injection in this case. Thanks in advance.
Upvotes: 0
Views: 367
Reputation: 16273
You haven't explained why you need to use a bean that implements the ActionListener
interface, instead of using a method qualifier as actionListener
attribute inside the UIComponent.
As you seem to have already tried, making CancelListener
a CDI bean is not enough for having it instantiated correctly: LoginBean will be null.
However, using the binding
attribute will force JSF to dynamically instantiate the bean, and this will make the trick:
<h:commandButton value="Cancel" immediate="true">
<f:actionListener binding="#{cancelListener}" type="mypackage.CancelListener" />
</h:commandButton>
As mentioned above, the class implementing ActionListener
must be a CDI bean as well:
@Named
@SessionScoped
public class CancelListener implements Serializable, javax.faces.event.ActionListener {
@Inject
private LoginBean loginBean;
@Override
public void processAction(ActionEvent event) throws AbortProcessingException {
System.out.println(this.toString());
System.out.println(loginBean.toString());
}
}
See also:
How does the 'binding' attribute work in JSF? When and how should it be used?
Upvotes: 2