Внедрение зависимостей JSF / CDI в ActionListener - PullRequest
0 голосов
/ 28 декабря 2018

Почему CDI не внедряет мой компонент поддержки (область сеанса) в этот ActionListener?Экземпляр loginBean всегда имеет значение null.У меня такое впечатление, что CDI не управляет экземплярами слушателя: это правильно?

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( "" );
    }

}

Вот определение моего класса LoginBean.

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;
    }

}

И мой слушатель подключен к кнопкес этим кодом:

<h:commandButton value="Cancel" immediate="true">
    <f:actionListener type="mypackage.CancelListener" />
</h:commandButton>

Я знаю, что могу использовать метод непосредственно на компоненте поддержки (связан с атрибутом тега actionListener) , но я хотел бы понять, как сделать мойКласс совместим с CDI и как форсировать инъекцию в этом случае.Заранее спасибо.

1 Ответ

0 голосов
/ 28 декабря 2018

Вы не объяснили , почему необходимо использовать компонент, реализующий интерфейс ActionListener, вместо использования квалификатора метода в качестве атрибута actionListener внутри UIComponent.

Как вы, похоже, уже пытались, сделать CancelListener bean-компонентом CDI недостаточно для его правильной реализации: LoginBean будет иметь значение null.

Однако использование атрибута binding заставит JSF динамически создавать экземплярbean, и это сделает трюк:

<h:commandButton value="Cancel" immediate="true">
    <f:actionListener binding="#{cancelListener}" type="mypackage.CancelListener" />
</h:commandButton>    

Как уже упоминалось выше, класс, реализующий ActionListener, также должен быть bean-компонентом CDI:

@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());
    }        
}

См. также:

Как работает атрибут 'binding' в JSF?Когда и как его следует использовать?

...