web-dev-qa-db-ja.com

FacesConverterへのCDIインジェクション

ほんの数回の検索から、これはしばらくの間存在している問題のようです。次のような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コンテナ。 Converterを使用しないように再コーディングする前に、誰かが解決策を提案できますか?

32
AlanObject

交換する

@FacesConverter(value = "categoryConverter")

沿って

@Named

そして使う

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

または

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

の代わりに

<h:inputSomething converter="categoryConverter" />

または

<f:converter converterId="categoryConverter" />

ちなみに、@EJB内の@FacesConverterにも同様の問題があります。ただし、JNDIが手動で取得する方法を提供します。 JSF 2.0での通信-@FacesConverterおよび@FacesValidatorでのEJBの取得 も参照してください。これにより、毎回手動で定義しなくても@FacesConverter(forClass=Category.class)を使用できます。残念ながら、CDI Beanでそれを実現する方法を頭から理解することはできません。


更新:たまたまJSFユーティリティライブラリ OmniFaces を使用すると、バージョン1.6で@Injectおよび@EJBを使用するための透過的なサポートが追加されます追加の構成やアノテーションのない@FacesConverterクラス。 CDI @FacesConverterショーケースの例 も参照してください。

62
BalusC

@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を使用すると、EEの人々はコーディング方法を忘れます。

5

@FacesConverterに@Advanced of CODIを使用するだけで Wiki を参照してください。

コンバーターまたはバリデーターに@Advancedの注釈が付けられるとすぐに、@ Injectを使用できます。

3
Dar Whi

BalusCの回答 ここ に従って、@ FacesConverterとConverterのみを含むJSF(requestscoped)マネージドBeanを追加して、アプリでこの問題を解決することにしました。JSFマネージドBeanからCDIマネージドBeanに移行しているためです。 。

@FacesConverterに対してCODI @Advancedを試しましたが、Beanをまったく注入しません。

2
Howard