0

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 = "james@mi6.uk";
    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.

Koor.fr
  • 55
  • 6
  • Normally, the setter is not mandatory and CDI can directly inject into a private attribute (using reflexion). I have added the setter but the result is the same. – Koor.fr Dec 28 '18 at 14:30
  • 1
    Why do you need to implement `ActionListener` interface? Usually you can define a bean method as `actionListener` in a UIComponent as explained in any JSF basic tutorial – perissf Dec 28 '18 at 14:55
  • Just for understand why CDI do not inject the backing bean. – Koor.fr Dec 28 '18 at 15:02
  • 3
    Because CancelListener is not a CDI or JSF managed bean. It's just a class that implements `ActionListener` interface. Not a bean. – perissf Dec 28 '18 at 15:06
  • Ok. But how can i said to CDI to manage event listeners (CancelListener instances)? – Koor.fr Dec 28 '18 at 15:18
  • Which jsf/cdi tutorial are you using? There us no indication your 'bean' is a managed bean at all, not is the scope visible/declared and you rarely need to implement the `ActionListener` interface. In normal applications not at all even. [mcve] please... – Kukeltje Dec 28 '18 at 15:54

1 Answers1

2

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?

perissf
  • 15,979
  • 14
  • 80
  • 117