将 CDI SessionScoped bean 注入 JSF ValueChangeListener

Injecting a CDI SessionScoped bean into a JSF ValueChangeListener

我正在尝试使用 javax.faces.event.ValueChangeListener 来对抗 h:selectOneMenu,就像这样

<h:selectOneMenu value="#{localeBean.languageCode}" onchange="submit()">
    <f:selectItem itemLabel="English" itemValue="en" />
    <f:selectItem itemLabel="German" itemValue="de" />
    <f:valueChangeListener  type="org.bitbucket.paulstat.jsf.event.ExampleValueChangeListener" />
</h:selectOneMenu>

这是监听器

import javax.faces.event.AbortProcessingException;
import javax.faces.event.ValueChangeEvent;
import javax.faces.event.ValueChangeListener;
import javax.inject.Inject;

import org.bitbucket.paulstat.jsf.localisation.LocaleBean;

public class ExampleValueChangeListener implements ValueChangeListener {

    @Inject
    private LocaleBean localeBean;

    @Override
    public void processValueChange(ValueChangeEvent event) throws AbortProcessingException {
        localeBean.setLanguageCode(event.getNewValue().toString());
        localeBean.switchLocale();
    }

}

还有 LocaleBean

import java.io.Serializable;
import java.util.Locale;

import javax.enterprise.context.SessionScoped;
import javax.faces.context.FacesContext;
import javax.inject.Named;

@Named
@SessionScoped
public class LocaleBean implements Serializable {

    private String languageCode;

    public void switchLocale() {
        FacesContext.getCurrentInstance().getViewRoot().setLocale(new Locale(languageCode));
    }

    public void setLanguageCode(String languageCode) {
        this.languageCode = languageCode;
    }

    public String getLanguageCode() {
        return languageCode;
    }

}

LocaleBean 似乎没有被注入到值更改侦听器中并且为空。我们可以将 SessionScoped CDI bean 与 JSF ValueChangeListeners 混合使用吗?

@Inject 仅适用于 CDI 管理的 bean。您的 ExampleValueChangeListener 不是 CDI 托管 bean。

合二为一。最简单的方法是在其上添加 @Named 注释,以便它在 EL 中可用。

@Named
public class ExampleValueChangeListener implements ValueChangeListener {
    // ...
}

通过 binding 而不是 type 引用它。

<f:valueChangeListener binding="#{exampleValueChangeListener}" />

另请参阅:

  • How to inject in @FacesValidator with @EJB, @PersistenceContext, @Inject, @Autowired
  • How to inject @EJB, @PersistenceContext, @Inject, @Autowired, etc in @FacesConverter?
  • Session scoped managed bean and actionListener