将 CDI 注入 FacesConverter
从几次搜索来看,这似乎是一个已经存在了一段时间的问题。我编写了一个 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();
}
}
正如您现在可能已经猜到的那样,我从未接受过注射。我从此页面得到了这个解决方法,看起来像这样:
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 容器。在我重新编码以不使用转换器之前,有人可以建议一个解决方案吗?
From just a few searches, this seems like a problem that has been around for a while. I have written a FacesConverter that looks like the following. The object Category is a JPA entity and CategoryControl is the DAO that fetches it.
@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();
}
}
As you probably guessed by now, I never get the injection. I got this workaround from this page, which looks like this.:
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.
However I can't make this work either. My backing bean creates and returns a converter all right, but it doesn't get the object injected into it.
I am using MyFaces CODI 1.0.1. With the current GlassFish/Weld container. Can anyone suggest a solution before I re-code to not use a Converter?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
替换
为
并使用
or
代替
or
顺便说一句,
@FacesConverter
内的@EJB
也存在类似的问题。然而,它提供了一种由 JNDI 手动获取的方法。另请参阅 JSF 2.0 中的通信 - 在 @FacesConverter 中获取 EJB和@FacesValidator。这样您就可以使用@FacesConverter(forClass=Category.class)
而无需每次都手动定义它。不幸的是,我无法从头顶上看出如何实现 CDI 豆的这一点。更新:如果您碰巧使用JSF实用程序库OmniFaces,由于版本1.6添加了对在
@FacesConverter
类中使用@Inject
和@EJB
,无需任何其他配置或注释。另请参阅CDI@FacesConverter
展示示例。Replace
by
and use
or
instead of
or
By the way, similar problem exist for
@EJB
inside a@FacesConverter
. It however offers a way to be grabbed by JNDI manually. See also Communication in JSF 2.0 - Getting an EJB in @FacesConverter and @FacesValidator. This way you can use a@FacesConverter(forClass=Category.class)
without manually defining it everytime. Unfortunately I can't tell from top of head how to realize that for CDI beans.Update: if you happen to use JSF utility library OmniFaces, since version 1.6 is adds transparent support for using
@Inject
and@EJB
in a@FacesConverter
class without any additional configuration or annotations. See also the CDI@FacesConverter
showcase example.@Inject
注解仅适用于 CDI 托管实例。如果您想在非 CDI 托管实例(如 JSF 验证器或 JSF 转换器)中使用 CDI 功能,您只需针对 CDI API 进行编程即可。这仅适用于至少 Java EE 7 + CDI 1.1 服务器。
https://docs.oracle.com/javaee /7/api/javax/enterprise/inject/spi/CDI.html
由于 Java EE 中的 AnnotationHell,人们忘记了如何编码。
The
@Inject
Annotation only works in CDI managed instances. If you want to use CDI features inside a non-CDI managed instance (Like a JSF Validator or a JSF Converter) you can just programm against the CDI API.This works only in at least Java EE 7 + CDI 1.1 server.
https://docs.oracle.com/javaee/7/api/javax/enterprise/inject/spi/CDI.html
With all the AnnotationHell in Java EE people forget how to code.
只需对 @FacesConverter 使用 CODI 的 @Advanced,请参阅 Wiki。
Just use @Advanced of CODI for your @FacesConverter see the Wiki.
根据 BalusC 的回答此处,我决定添加仅包含 @FacesConverter 和 Converter 的 JSF(requestscoped)托管 bean 来解决此问题在我的应用程序中,因为我正在从 JSF 托管 Bean 迁移到 CDI 托管 Bean。
我尝试了 CODI @Advanced 和 @FacesConverter,但它根本不注入 bean。
Per BalusC's answer here, I decided to add JSF (requestscoped) managed beans that only contained @FacesConverter and Converter to resolve this issue in my app, since I'm migrating from JSF managed beans to CDI managed beans.
I tried CODI @Advanced against @FacesConverter, but it does not inject the bean at all.