Integración de JAX-RS 2.0 con EJB y CDI
Java™ API for RESTful Web Services (JAX-RS) 2.0 se integra con Enterprise JavaBeans (EJB) y Contexts and Dependency Injection (CDI) en la versión 9 de WebSphere Application Server tradicional.
Para que JAX-RS 2.0 funcione con los enterprise beans, debe utilizar @Path para anotar la clase de un bean y convertirla en una clase de recurso raíz.
Al integrarse con EJB, el usuario puede anotar los beans EJB para mostrarlos como puntos finales de REST. También puede utilizar Java Transaction API (JTA) y las funciones de seguridad de EJB. JAX-RS 2.0 en WebSphere Application Server tradicional da soporte a la utilización de beans de sesión sin estado y singleton como clases, proveedores y subclases de aplicaciones de recursos raíz.
Gracias a integración con CDI, puede anotar beans CDI o beans gestionados como puntos finales REST, y utilizar la inyección de CDI para los servicios web. JAX-RS 2.0 en WebSphere Application Server tradicional da soporte a beans de estilo CDI como clases, proveedores y subclases de aplicaciones de recursos raíz. Los proveedores y las subclases de aplicación deben ser singletons o utilizar el ámbito de aplicación. La especificación CDI facilita la integración de componentes Java EE de distinto tipo. Se proporciona un mecanismo común para inyectar componentes como, por ejemplo componentes EJB o beans gestionados, en otros componentes como, por ejemplo, Java Server Pages (JSP) u otros EJB.
- Para un bean de sesión sin estado, utilice la anotación
@Stateless como se muestra en el ejemplo siguiente:
@Stateless @Path("stateless-bean") public class StatelessResource {...}
- Para un bean singleton, utilice la anotación @Singleton
como se muestra en el ejemplo siguiente:
@Singleton @Path("singleton-bean") public class SingletonResource {...}
@ApplicationScoped
@Path("/ApplicationScopedResource")
public class ApplicationScopedResource {
private @Inject
SimpleBean injected;
...
}
Restricciones en JAX-RS 2.0 con EJB y CDI
Consulte en los elementos siguientes las restricciones de JAX-RS 2.0 en WebSphere Application Server tradicional:
- Si utiliza EJB como un recurso JAX-RS, proveedor o aplicación, no puede utilizar la
inyección de @Context en el constructor del bean EJB. Nota: El motivo de este caso es que el EJB con el constructor predeterminado solamente se puede utilizar para JAX-RS basado en la especificación de EJB y JAX-RS.
- Para una clase de aplicación, si no se implementa ninguna interfaz o si tiene la anotación @Localbean, se considera como EJB. Pero si se implementan interfaces locales o POJO, no se considera como EJB.
- Para un proveedor, a continuación se listan las condiciones por las que una clases se puede considerar o no como proveedor EJB válido:
- Si una clase implementa las interfaces de proveedor POJO sólo sin la anotación @Local, se considera un proveedor de EJB válido.
- Si una clase tiene la anotación @LocalBean e implementa la interfaz de proveedor POJO, se considera un proveedor EJB válido.
- Si una clase tiene la interfaz local con la anotación @Local, la interfaz local es una interfaz de proveedor. Si esta clase implementa la interfaz de proveedor, será un proveedor EJB válido.
- Si una clase tiene una interfaz local con la anotación @Local y si la interfaz local no es una interfaz de proveedor, no será un proveedor válido. El motivo de este caso es que el contenedor EJB puede generar un apéndice EJB sólo para la interfaz local en lugar de hacerlo para la interfaz del proveedor POJO.
- Si una clase tiene la anotación @Local pero la anotación no implementa la interfaz de proveedor a la que hace referencia, no será un proveedor válido. En base a la especificación de JAX-RS 2.0, un proveedor es una clase que implementa una interfaz JAX-RS, o más de una, que se introduce en esta especificación y que se puede anotar mediante @Provider para un descubrimiento automático.
- En el caso de un recurso, a continuación se enumeran las condiciones en que los métodos de una clase están o no disponibles como recursos JAX-RS:
- Si el recurso basado en EJB no implementa ninguna interfaz, todos los métodos que se declaran en esta clase están disponibles como recursos JAX-RS.
- Si el recurso basado en EJB implementa una interfaz (local o POJO), todos los métodos que se hayan declarado en la interfaz estarán disponibles como recursos JAX-RS.
- Si el recurso basado en EJB implementa una interfaz múltiple,
- Si todas las interfaces son interfaces POJO sin la anotación @Local, todos los métodos que se hayan declarado en la interfaz estarán disponibles como recursos JAX-RS.
- Si todas las interfaces son interfaces locales con la anotación @Local, todos los métodos que se hayan declarado en la interfaz estarán disponibles como recursos JAX-RS.
- Si alguna de las interfaces es una interfaz local con la anotación @Local, mientras las demás no son interfaces locales, solamente estarán disponibles como recursos JAX-RS aquellos métodos que se hayan declarado en las interfaces locales. Nota: El motivo de este caso es que el contenedor EJB puede generar un apéndice EJB para las interfaces locales solamente en este caso de ejemplo.
- Si el recurso basado en EJB tiene la anotación @LocalBean, todos los métodos que se hayan declarado en la clase estarán disponibles como recursos JAX-RS.
- Si el recurso basado en EJB implementa una interfaz, el método de recursos JAX-RS se debe declarara en la interfaz. Si la interfaz es un proveedor que no se puede modificar, deberá crear una interfaz nueva para que la clase de recurso añada el método de recursos. De lo contrario, no se considera un recurso EJB.
- si una clase de recurso con la anotación @Path implementa la interfaz de proveedor JAX-RS o se declara con la anotación @Provider, esta clase funcionará como recurso y como proveedor. En este caso, de forma predeterminada, el motor de JAX-RS 2.0 utiliza sólo una instancia de esta clase compartida por el recurso y el proveedor, y el ciclo de vida de la instancia es singleton.
- Si una clase se registra en los métodos getClasses y getSingletons de la clase de aplicación, de forma predeterminada, el motor de JAX-RS 2.0 utilizará la instancia desde el método getSingletons y hará caso omiso del registro en el método getClasses.
- Si un recurso RESTful también es un bean gestionado CDI y su ámbito es javax.enterprise.context.Dependent, el método PreDestroy no puede invocarse debido a la restricción CDI.
Ciclo de vida del bean JAX-RS 2.0 y el bean EJB
Aplicación | JAX-RS 2.0 | EJB | Resultado |
---|---|---|---|
Recurso | perRequest | Sin estado | Sin estado |
perRequest | Singleton | Singleton | |
Singleton | Sin estado | Sin estado | |
Singleton | Singleton | Singleton | |
Proveedor | Singleton | Sin estado | Sin estado |
Singleton | Singleton | Singleton |
Ciclo de vida del ámbito de JAX-RS 2.0 y el ámbito de CDI
Aplicación | Ámbito de JAX-RS 2.0 | Anotación del ámbito de CDI | Resultado |
---|---|---|---|
Recurso | perRequest | @ApplicationScoped | Singleton |
perRequest | @RequestScoped | perRequest | |
perRequest | @Dependent | perRequest | |
perRequest | @SessionScoped | Sesión | |
perRequest | perRequest | ||
Singleton | @ApplicationScoped | Singleton | |
Singleton | @RequestScoped | perRequest | |
Singleton | @Dependent | Singleton | |
Singleton | @SessionScoped | Sesión | |
Singleton | Singleton | ||
Proveedor | Singleton | @ApplicationScoped | Singleton |
Singleton | @RequestScoped | Singleton | |
Singleton | @Dependent | Singleton | |
Singleton | @SessionScoped | Singleton | |
Singleton | Singleton |
Mensajes de conflicto de ciclo de vida del ámbito de JAX-RS 2.0 y el ámbito de CDI
Aparecen los siguientes mensajes de aviso cuando el ciclo de vida del ámbito de JAX-RS 2.0 y CDI entran en conflicto. Son mensajes de aviso y no es necesario realizar ninguna acción.
Este mensaje se visualiza si el ámbito del recurso JAXRS-2.0 no coincide con el ámbito de CDI y existe la instancia de recursos en CDI; por lo que WebSphere Application Server tradicional obtiene la instancia de recursos de CDI. La instancia no incluye la inyección de CDI si proviene de JAXRS.CWWKW1001W: El ámbito {1} del recurso JAXRS-2.0 {0} no coincide con el ámbito de CDI {2}. La versión tradicional de WebSphere Application Server obtiene la instancia de recursos de {3}.
Este mensaje aparece porque la instancia de proveedor es sólo singleton. WebSphere Application Server tradicional obtiene la instancia de proveedor de CDI si el ámbito de CDI del proveedor es Dependent o ApplicationScoped. La instancia no incluye la inyección de CDI si proviene de JAXRS.CWWKW1002W: El ámbito de CDI del proveedor JAXRS-2.0 {0} es {1}. La versión tradicional de WebSphere Application Server obtiene la instancia de proveedor de {2}.