CDI注入FacesConverter

Ala*_*ect 30 myfaces cdi jsf-2

从一些搜索来看,这似乎已经存在了一段时间的问题.我写了一个看起来如下的FacesConverter.对象Category是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();
}

}
Run Code Online (Sandbox Code Playgroud)

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

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.
Run Code Online (Sandbox Code Playgroud)

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

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

Bal*_*usC 62

更换

@FacesConverter(value = "categoryConverter")
Run Code Online (Sandbox Code Playgroud)

通过

@Named
Run Code Online (Sandbox Code Playgroud)

并使用

<h:inputSomething converter="#{categoryConverter}" />
Run Code Online (Sandbox Code Playgroud)

要么

<f:converter binding="#{categoryConverter}" />
Run Code Online (Sandbox Code Playgroud)

代替

<h:inputSomething converter="categoryConverter" />
Run Code Online (Sandbox Code Playgroud)

要么

<f:converter converterId="categoryConverter" />
Run Code Online (Sandbox Code Playgroud)

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


更新:如果您碰巧使用JSF实用程序库OmniFaces,因为版本1.6增加了对使用@Inject@EJB@FacesConverter类中的透明支持,而无需任何其他配置或注释.另请参阅CDI @FacesConverter展示示例.

  • 好吧,我会被愚弄.我实现了一个解决方法,基本上调用应用程序来评估转换器内部的表达式,但我认为这更优雅.所以我还有另一个问题@BalusC - 不是你写JSF书的时候吗? (3认同)
  • 别客气.至于这本书,你到目前为止还不是第一个问这个的人...... (3认同)
  • 那么你可以相信它在原始发布后差不多一年我又在一个新项目中遇到这个问题,进行谷歌搜索,然后自带帖子!我不记得上面写的但电脑从不说谎. (3认同)
  • @Jin:对不起,我很直(已经被占领). (3认同)

Sur*_*nut 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 {
     ....
    }
}
Run Code Online (Sandbox Code Playgroud)

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

使用Java EE中的所有AnnotationHell,人们忘记了如何编码.