Iniezione CDI in un FacesConverter

Da poche ricerche, questo sembra un problema che è stato in giro per un po ‘. Ho scritto un FacesConverter che assomiglia al seguente. La categoria object è un’entity framework JPA e CategoryControl è il DAO che lo recupera.

@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(); } } 

Come probabilmente hai indovinato, non ho mai ricevuto l’iniezione. Ho ottenuto questo trucco da questa pagina , che assomiglia a questo .:

 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. 

Tuttavia non posso fare questo lavoro neanche. Il mio backing bean crea e restituisce un convertitore, ma non viene iniettato dall’object.

Sto usando MyFaces CODI 1.0.1. Con l’attuale contenitore GlassFish / Weld. Qualcuno può suggerire una soluzione prima di ricodificare per non utilizzare un convertitore?

Sostituire

 @FacesConverter(value = "categoryConverter") 

di

 @Named 

e usare

  

o

  

invece di

  

o

  

A proposito, esiste un problema simile per @EJB all’interno di @FacesConverter . Offre tuttavia un modo per essere afferrato manualmente da JNDI. Vedi anche Comunicazione in JSF 2.0 – Ottenere un EJB in @FacesConverter e @FacesValidator . In questo modo puoi usare @FacesConverter(forClass=Category.class) senza definirlo manualmente ogni volta. Sfortunatamente non posso dire da capo come realizzarlo per i fagioli CDI.


Aggiornamento : se si utilizza la libreria di utilità JSF OmniFaces , poiché la versione 1.6 aggiunge il supporto trasparente per l’utilizzo di @Inject e @EJB in una class @FacesConverter senza alcuna configurazione o annotazione aggiuntiva. Vedi anche l’esempio della vetrina CDI @FacesConverter .

L’annotazione @Inject funziona solo nelle istanze gestite da CDI. Se si desidera utilizzare le funzionalità CDI all’interno di un’istanza gestita non-CDI (come un validatore JSF o un convertitore JSF), è ansible semplicemente programmare contro l’API CDI.

Funziona solo con almeno 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

Con tutti gli AnnotationHell in Java EE le persone dimenticano come codificare.

Basta usare @Advanced di CODI per il tuo @FacesConverter vedere il Wiki .

Non appena un convertitore o un validatore viene annotato con @Advanced, è ansible utilizzare @Inject.

Per la risposta di BalusC qui , ho deciso di aggiungere bean gestiti JSF (requestcoped) che contenevano solo @FacesConverter e Converter per risolvere questo problema nella mia app, dal momento che sto migrando da bean gestiti JSF a bean gestiti CDI.

Ho provato CODI @Advanced contro @FacesConverter, ma non inietta affatto il bean.