从几次搜索开始,这似乎已经存在了一段时间的问题。我写了一个看起来如下的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容器。在我重新编码以不使用转换器之前,有人可以建议解决方案吗?
答案 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。