2011-09-23 85 views
24

從幾次搜索中,這似乎就像是一個已經存在一段時間的問題。我寫了一個如下所示的FacesConverter。對象類別是JPA實體,並且類別控制是提取它的DAO。將CDI注入FacesConverter

@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容器。任何人都可以在我重新編碼不使用轉換器之前提出解決方案嗎?

回答

53

替換

@FacesConverter(value = "categoryConverter") 

通過

@Named 

並使用

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

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

inste的

<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豆。


更新:如果你碰巧使用JSF工具庫OmniFaces,因爲1.6版是增加了一個@FacesConverter類使用@Inject@EJB沒有任何額外的配置或註解透明的支持。另見the CDI @FacesConverter showcase example

+3

嗯,我會被淹沒。我實現了一個基本上調用應用程序來評估轉換器內部表達式的解決方法,但我認爲這更優雅。所以我有另一個問題@BalusC - 是不是你寫了一本關於JSF的書的時間? – AlanObject

+3

不客氣。至於這本書,你到目前爲止不是第一個問這個問題的人...... – BalusC

+0

好吧,它不像你必須寫很多 - 只是編輯你已經寫的所有東西。說真的,如果你對一個合作感興趣的話,我已經想到了一本書的大綱,只是讓我知道。 – AlanObject

3

只需使用@Advanced的CODI爲您的@FacesConverter查看Wiki

只要轉換器或驗證程序使用@Advanced註釋,就可以使用@Inject。

2

每BalusC的回答here,我決定加入JSF(requestscoped)管理豆類,只有包含@FacesConverter器和轉換器在我的應用程序來解決這個問題,因爲我從遷移JSF託管豆CDI管理的Bean。

我對@FacesConverter嘗試了CODI @Advanced,但它根本沒有注入bean。

6

@Inject註釋僅適用於CDI託管實例。如果您想在非CDI託管實例內使用CDI功能(如JSF驗證程序或JSF轉換程序),則可以對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

與所有的AnnotationHell在Java EE的人忘記了如何編寫代碼。