Инъекция CDI в FacesConverter - PullRequest
       27

Инъекция CDI в FacesConverter

30 голосов
/ 23 сентября 2011

После нескольких поисков это кажется проблемой, которая существует уже некоторое время.Я написал 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();
}

}

Как вы уже, наверное, догадались, я никогда не получу инъекцию.Я получил этот обходной путь от этой страницы , который выглядит следующим образом.: * 10101 *

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.

Однако я тоже не могу сделать эту работу.Мой бэк-бин хорошо создает и возвращает конвертер, но не вводит в него объект.

Я использую MyFaces CODI 1.0.1.С текущим контейнером GlassFish / Weld.Может кто-нибудь предложить решение, прежде чем я перекодировать, чтобы не использовать конвертер?

Ответы [ 4 ]

62 голосов
/ 23 сентября 2011

Замените

@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 - Получение EJB в @FacesConverter и @ FacesValidator .Таким образом, вы можете использовать @FacesConverter(forClass=Category.class), не определяя его каждый раз вручную.К сожалению, я не могу понять, как это реализовать для компонентов CDI.


Обновление : если вы используете библиотеку утилит JSF OmniFaces , поскольку в версии 1.6 добавлена ​​прозрачная поддержка использования @Inject и @EJB в классе @FacesConverter без каких-либо дополнительных настроек или аннотаций.См. Также пример витрины CDI @FacesConverter .

5 голосов
/ 08 октября 2015

Аннотация @Inject работает только в управляемых экземплярах CDI. Если вы хотите использовать функции CDI внутри экземпляра, не управляемого CDI (например, JSF Validator или JSF Converter), вы можете просто программировать с использованием API CDI.

Это работает только по крайней мере на сервере 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 люди забывают, как кодировать.

3 голосов
/ 25 сентября 2011

Просто используйте @Advanced of CODI для своего @FacesConverter, см. Wiki .

Как только конвертер или валидатор аннотируются @Advanced, можно использовать @ Inject.

2 голосов
/ 20 ноября 2012

Согласно ответу BalusC здесь , я решил добавить управляемые bean-компоненты JSF (requestcoped), которые содержали только @FacesConverter и Converter, чтобы решить эту проблему в моем приложении, так как я мигрирую из управляемых bean-компонентов JSF в CDIуправляемые bean-компоненты.

Я пробовал CODI @Advanced против @FacesConverter, но он вообще не внедряет bean-компоненты.

...