validator getasstring faces ejemplo attribute jsf-2 cdi myfaces

jsf 2 - getasstring - Inyección de CDI en un FacesConverter



h selectonemenu converter (4)

La anotación @Inject solo funciona en instancias administradas por CDI. Si desea usar funciones de CDI dentro de una instancia administrada que no es CDI (como un Validador de JSF o un Convertidor de JSF), puede programar contra la API de CDI.

Esto funciona solo en al menos el servidor 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

Con todo el AnnotationHell en Java EE, la gente olvida cómo codificar.

De solo algunas búsquedas, esto parece ser un problema que ha existido por un tiempo. He escrito un FacesConverter que se parece a lo siguiente. El objeto Category es una entidad JPA y CategoryControl es el DAO que 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(); } }

Como probablemente ya habrás adivinado, nunca recibo la inyección. Obtuve esta solución de esta página , que se ve así:

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.

Sin embargo, tampoco puedo hacer que esto funcione. Mi bean de respaldo crea y devuelve un convertidor bien, pero no obtiene el objeto inyectado en él.

Estoy usando MyFaces CODI 1.0.1. Con el contenedor GlassFish / Weld actual. ¿Alguien puede sugerir una solución antes de volver a codificar para no usar un convertidor?


Reemplazar

@FacesConverter(value = "categoryConverter")

por

@Named

y use

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

o

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

en lugar de

<h:inputSomething converter="categoryConverter" />

o

<f:converter converterId="categoryConverter" />

Por cierto, existe un problema similar para @EJB dentro de @FacesConverter . Sin embargo, ofrece una forma de ser agarrado por JNDI manualmente. Consulte también Comunicación en JSF 2.0 - Obtención de un EJB en @FacesConverter y @FacesValidator . De esta forma puede usar @FacesConverter(forClass=Category.class) sin definirlo manualmente cada vez. Desafortunadamente no puedo decir desde lo alto de la cabeza cómo darse cuenta de que para los frijoles CDI.

Actualización : si usa la biblioteca de utilidades JSF OmniFaces , la versión 1.6 agrega soporte transparente para usar @Inject y @EJB en una clase @FacesConverter sin ninguna configuración adicional o anotaciones. Ver también el ejemplo de presentación de CDI @FacesConverter .


Según la respuesta de BalusC here , decidí agregar frijoles administrados JSF (requestscoped) que solo contenían @FacesConverter y Converter para resolver este problema en mi aplicación, ya que estoy migrando de beans gestionados de JSF a beans administrados por CDI.

Probé CODI @Advanced contra @FacesConverter, pero no inyecta el bean en absoluto.


Simplemente use @Advanced of CODI para su @FacesConverter vea la Wiki .

Tan pronto como un convertidor o un validador se anota con @Advanced, es posible utilizar @Inject.