将 CDI 注入 FacesConverter

发布于 2024-12-06 07:53:21 字数 1367 浏览 3 评论 0原文

从几次搜索来看,这似乎是一个已经存在了一段时间的问题。我编写了一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

隐诗 2024-12-13 07:53:21

替换

@FacesConverter(value = "categoryConverter")

@Named

并使用

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

or

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

代替

<h:inputSomething converter="categoryConverter" />

or

<f:converter converterId="categoryConverter" />

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


更新:如果您碰巧使用JSF实用程序库OmniFaces,由于版本1.6添加了对在 @FacesConverter 类中使用 @Inject@EJB,无需任何其他配置或注释。另请参阅CDI @FacesConverter 展示示例

Replace

@FacesConverter(value = "categoryConverter")

by

@Named

and use

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

or

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

instead of

<h:inputSomething converter="categoryConverter" />

or

<f:converter converterId="categoryConverter" />

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.

扎心 2024-12-13 07:53:21

@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,人们忘记了如何编码。

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.

@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

With all the AnnotationHell in Java EE people forget how to code.

请远离我 2024-12-13 07:53:21

只需对 @FacesConverter 使用 CODI 的 @Advanced,请参阅 Wiki。

一旦转换器或验证器使用@Advanced进行注释,就可以使用@Inject。

Just use @Advanced of CODI for your @FacesConverter see the Wiki.

As soon as a converter or a validator is annotated with @Advanced it's possible to use @Inject.

温馨耳语 2024-12-13 07:53:21

根据 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文