CDI注入FacesConverter

时间:2011-09-23 15:35:33

标签: jsf-2 cdi myfaces

从几次搜索开始,这似乎已经存在了一段时间的问题。我写了一个看起来如下的FacesConverter。对象类别是JPA实体, CategoryControl 是获取它的DAO。

@FacesConverter(value = "categoryConverter")
public class CategoryConverter implements Converter {

@Inject private CategoryControl cc;

public CategoryConverter() { }

@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
    if (cc != null) return cc.getByName(value);
    System.out.println("CategoryConverter().getAsObject(): no injection!");
    return null;
}

@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
    if (!(value instanceof Category)) return null;
    return ((Category) value).getName();
}

}

你可能已经猜到了,我从来没有注射过。我从this page得到了这个解决方法,看起来像这样。:

Workaround for this problem: create this method in your localeController: 

public Converter getConverter() 
{ 
    return   FacesContext.getCurrentInstance().getApplication().createConverter("localeConverter"); 
} 

and use converter="#{localeController.converter}" in your h:selectOneMenu.

然而我也无法做到这一点。我的支持bean可以创建并返回一个转换器,但它不会将对象注入其中。

我正在使用MyFaces CODI 1.0.1。使用当前的GlassFish / Weld容器。在我重新编码以不使用转换器之前,有人可以建议解决方案吗?

4 个答案:

答案 0 :(得分:61)

替换

@FacesConverter(value = "categoryConverter")

通过

@Named

并使用

<h:inputSomething converter="#{categoryConverter}" />

<f:converter binding="#{categoryConverter}" />

而不是

<h:inputSomething converter="categoryConverter" />

<f:converter converterId="categoryConverter" />

顺便说一句,@EJB内的@FacesConverter存在类似的问题。然而,它提供了一种手动抓取JNDI的方法。另见Communication in JSF 2.0 - Getting an EJB in @FacesConverter and @FacesValidator。这样您就可以使用@FacesConverter(forClass=Category.class)而无需每次都手动定义它。不幸的是,我无法从头顶知道如何实现CDI bean。


更新:如果您碰巧使用JSF实用程序库OmniFaces,因为版本1.6增加了对@Inject@EJB @FacesConverter的透明支持1}}没有任何附加配置或注释的类。另请参阅the CDI @FacesConverter showcase example

答案 1 :(得分:5)

@Inject注释仅适用于CDI托管实例。如果要在非CDI托管实例(如JSF验证器或JSF转换器)中使用CDI功能,则可以针对CDI API进行编程。

这仅适用于至少Java EE 7 + CDI 1.1服务器。

@FacesValidator("userNameValidator")
public class UserNameValidator implements Validator {

    private UserService userService;

    public UserNameValidator(){
        this.userService = CDI.current().select(UserService.class).get();
    }

    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
     ....
    }
}

https://docs.oracle.com/javaee/7/api/javax/enterprise/inject/spi/CDI.html

Java EE中的所有AnnotationHell都会忘记如何编码。

答案 2 :(得分:3)

为@FacesConverter使用CODI的@Advanced,请参阅Wiki

  

只要使用@Advanced注释转换器或验证器,就可以使用@Inject。

答案 3 :(得分:2)

根据BalusC的回答here,我决定添加仅包含@FacesConverter和Converter的JSF(请求编译)托管bean来解决我的应用中的这个问题,因为我正在从JSF托管bean迁移到CDI托管bean

我对@FacesConverter尝试了CODI @Advanced,但它根本没有注入bean。