Si tiene aplicaciones EJB (Enterprise JavaBeans)
que se exponen utilizando una vista de interfaz local, puede exponer una instancia RESTful al enterprise bean
utilizando JAX-RS (API Java™ para servicios web RESTful).
Mediante la implementación de enterprise beans JAX-RS anotados, puede mantener la funcionalidad EJB incluyendo el soporte de transacciones,
la inyección de componentes y recursos Java EE y otras funciones de bean de sesión EJB.
Antes de empezar
Antes de EJB 3.1, los enterprise beans que requerían una vista de cliente local EJB también
requerían una interfaz Java diferente, normalmente ubicada en un archivo aparte,
que declaraba los métodos de vista local. El enterprise bean especificaba que implementaba la interfaz de vista local EJB mediante descriptores de despliegue o anotaciones EJB.
Mediante la especificación EJB 3.1, tiene la opción de exponer una vista local de un enterprise bean sin una interfaz local EJB explícita.
En su lugar, el enterprise bean tiene una vista de cliente sin interfaz que se basa en métodos públicos de la clase de bean. Los enterprise
beans de vista sin interfaz pueden ser más sencillos de desarrollar que un enterprise bean de vista local por las razones siguientes:
- Los enterprise beans de vista sin interfaz no requieren una declaración de interfaz Java aparte.
- Los enterprise beans de vista sin interfaz no requieren la especificación de metadatos adicionales en el descriptor de despliegue
o al utilizar anotaciones.
Consulte la especificación EJB 3.1 para obtener más detalles sobre las vistas sin interfaz
de un enterprise bean.
JAX-RS da soporte al uso de enterprise beans que declaren una interfaz empresarial local y
enterprise beans de vista sin interfaz.
Esta tarea describe la implementación de vistas RESTful de un enterprise bean con una interfaz local
para habilitar el enterprise bean para exponer recursos JAX-RS.
Acerca de esta tarea
Puede crear un enterprise bean simple con anotaciones JAX-RS.
Aunque esta tarea describe específicamente cómo implementar vistas RESTful de un enterprise bean de vista de interfaz local, es importante
que tenga en cuenta el ámbito completo de la arquitectura de la aplicación y cómo desea exponer los recursos cuando decida el modelo de recursos y
determinar qué vistas RESTful son adecuadas para la aplicación de enterprise beans. Estas consideraciones quedan fuera del ámbito de esta tarea.
JAX-RS
da soporte a beans de sesión monoinstancia (singleton) y sin estado.
Puede añadir anotaciones JAX-RS a la interfaz local de un bean de sesión. Además, con EJB 3.1, puede añadir anotaciones JAX-RS directamente a una clase EJB
si el enterprise bean expone una vista sin interfaz.
Con las reglas de empaquetado de EJB 3.1, puede añadir enterprise beans JAX-RS en el archivo
WAR (Web Application Archive) directamente en el directorio WEB-INF/classes o utilizando un archivo JAR (Java Archive)
en el directorio WEB-INF/lib. Puede declarar un enterprise bean utilizando anotaciones o utilizando un descriptor de despliegue EJB o utilizando ambos.
No se da soporte a enterprise beans anotados JAX-RS en un archivo ejb-jar separado o autónomo incluido en un EAR.
Best practice: Aunque puede declarar enterprise beans de diferentes formas,
se trata de un procedimiento recomendado para implementar directamente la interfaz local de empresa EJB y para declarar siempre la anotación
@javax.ejb.Local. Utilizando este método, el bean EJB es necesario para implementar la interfaz empresarial local, que elimina los errores
al especificar nombres de método y los cambios en los tipos de argumento. Utilizando siempre la anotación @javax.ejb.Local,
si hay alguna vez varias interfaces empresariales, puede simplemente añadir la interfaz empresarial al valor de la anotación. También puede utilizar
este enfoque para modificar el enterprise bean utilizando un descriptor de despliegue.
bprac
Procedimiento
- Cree interfaces locales de enterprise bean para la aplicación de enterprise bean. En el ejemplo siguiente se muestra una sencilla interfaz empresarial local, la interfaz local EJB Purchasable, para los elementos que se comprarán:
package com.example.jaxrs;
@javax.ws.rs.Path("itemsForPurchase/{itemID}")
public interface Purchasable {
public int getItemsLeft(String itemID);
@javax.ws.rs.POST
public Order purchase(
@javax.ws.rs.PathParam("itemID") String itemID,
@javax.ws.rs.QueryParam("orderId") String orderID);
}
El método getItemsLeft es un método EJB regular que no está ralacionado con JAX-RS. Una anotación javax.ws.rs.Path
indica la vía de acceso de solicitud HTTP que se utilizará. Cuando se realiza una solicitud HTTP POST en el objeto itemsForPurchase/{itemID},
el entorno de ejecución de JAX-RS encuentra un bean EJB que implementa la interfaz local Purchasable e invoca el método de compra en el enterprise bean.
Puede seguir utilizando el método de compra fuera de una solicitud de entorno de ejecución JAX-RS. Puede utilizar la inyección o una búsqueda JNDI
para un enterprise bean comprable e invocar el método de compra con los dos argumentos de Serie, itemID y orderID.
Best practice: Si hay varios enterprise beans que implementan una interfaz empresarial local, el entorno de ejecución JAX-RS elige
un bean EJB aleatorio para utilizarlo cuando se realice una solicitud JAX-RS. Se trata de un procedimiento recomendado para habilitar sólo una clase de
bean para implementar una interfaz local EJB anotada JAX-RS. Si es necesario, cree una interfaz local EJB aparte, utilice las anotaciones JAX-RS en la nueva interfaz y,
a continuación, modifique los metadatos de la clase de bean, de modo que implemente la interfaz local EJB nueva.
bprac
- Cree el enterprise bean que implementa la interfaz empresarial local. En el ejemplo siguiente se muestra el bean EJB comprable:
public int getItemsLeft(String itemID) {
// Devolver el número de artículos restantes.
}
public Order purchase(String itemID, String orderId) {
// Añadir el artículo proporcionado al ID de pedido y devolverlo.
}
}
- Declare que la clase Book es un enterprise bean e implementa una interfaz local. Utilice uno de los métodos siguientes para declarar la clase como un enterprise bean que implementa la interfaz local.
En el ejemplo siguiente, la clase Book se declara en un enterprise bean que implementa una interfaz local:
- Utilice las anotaciones EJB @javax.ejb.Stateless o @javax.ejb.Singleton
en la clase Book para especificar que desea que el EJB para sea sin estado o singleton.
Además, añada la anotación @javax.ejb.Local con las interfaces locales como el valor de la anotación; por ejemplo:
@javax.ejb.Stateless
@javax.ejb.Local(Purchasable.class)
public class Book {
Si ha implementado varias interfaces empresariales locales, añada las clases de interfaz al valor de la anotación
@javax.ejb.Local; por ejemplo:
@javax.ejb.Local({Purchasable.class, Rentable.class})
- Puede utilizar un descriptor de despliegue para declarar un bean EJB y las interfaces empresariales que implementa; por ejemplo:
<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" version="3.1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd">
<!--
Este archivo debe existir en el directorio WEB-INF/
del archivo WAR. Consulte la especificación EJB 3.1 20.4 para obtener más detalles.
-->
<enterprise-beans>
<session>
<ejb-name>Book</ejb-name>
<business-local>com.example.jaxrs.Purchasable</business-local>
<ejb-class>com.example.jaxrs.Book</ejb-class>
<session-type>Stateless</session-type>
</session>
</enterprise-beans>
</ejb-jar>
Si ha implementado varias interfaces empresariales locales, debe añadir elementos business-local a cada interfaz local en la definición de bean.
- Si sólo tiene una interfaz empresarial local, puede implementar la interfaz directamente; por ejemplo:
@javax.ejb.Stateless
public class Book implements Purchasable {
- (opcional) Añada propiedades y campos de recursos Java EE anotados @javax.annotation.Resource
a las clases EJB JAX-RS para acceder fácilmente a recursos de la aplicación. Las inyecciones Java EE no funcionan en clases Java sin formato
con anotaciones JAX-RS. La inyección de propiedades y campos de recursos Java EE
anotados @javax.annotation.Resource a las clases EJB JAX-RS sólo funciona si las clases anotadas JAX-RS son enterprise bean o
un bean gestionado JCDI (Java Context
and Dependency Injection) (JSR-299); por ejemplo:
package com.example.jaxrs;
@javax.ejb.Stateless
@javax.ejb.Local(Purchasable.class)
public class Book implements Purchasable {
@javax.annotation.Resource(name="jdcb/TestDataSource")
private javax.sql.DataSource datasource;
public int getItemsLeft(String itemID) {
// Lee del origen de datos.
// Devuelve el número de elementos que quedan.
}
public Order purchase(String itemID, String orderId) {
// Lee del origen de datos.
// Añade el artículo proporcionado al pedido y lo devuelve.
}
}
En este ejemplo, si un origen de datos está configurado correctamente
con el nombre JNDI correcto, se inyecta un objeto DataSource en la clase de recurso.
- (opcional) Utilice la inyección JAX-RS @javax.ws.rs.core.Context para obtener acceso a información
sobre la solicitud. Puede añadir un campo @javax.ws.rs.core.Context UriInfo a la clase EJB JAX-RS
para acceder a información sobre el URI de solicitud; por ejemplo:
package com.example.jaxrs;
@javax.ejb.Stateless
@javax.ejb.Local(Purchasable.class)
public class Book implements Purchasable {
@javax.ws.rs.core.Context
private UriInfo uriInfo;
public int getItemsLeft(String itemID) {
// Devolver el número de artículos restantes.
}
public Order purchase(String itemID, String orderId) {
// Añadir el artículo proporcionado al ID de pedido y devolverlo.
}
}
Para leer parámetros de la solicitud como por ejemplo @javax.ws.rs.HeaderParam,
@javax.ws.rs.QueryParam y @javax.ws.rs.PathParam, añada un parámetro al método de recurso, por ejemplo:
package com.example.jaxrs;
@javax.ws.rs.Path("itemsForPurchase/{itemID}")
public interface Purchasable {
public int getItemsLeft(String itemID);
@javax.ws.rs.POST
public Order purchase(
@javax.ws.rs.PathParam("itemID") String itemID,
@javax.ws.rs.QueryParam("orderId") String orderID);
}
package com.example.jaxrs;
@javax.ejb.Stateless
@javax.ejb.Local(Purchasable.class)
public class Book implements Purchasable {
@javax.ws.rs.core.Context
private UriInfo uriInfo;
public int getItemsLeft(String itemID) {
// Devuelve el número de elementos que quedan.
}
public Order purchase(String itemID, String orderId) {
// Los parámetros del método contienen los valores de solicitud.
// Añadir el artículo proporcionado al ID de pedido y devolverlo.
}
/* El campo siguiente no se establecerá. */
@javax.ws.rs.QueryParam("q")
private String willNotWork;
@javax.ws.rs.QueryParam("q")
public void setMyQueryParam(String q) {
/* Esta propiedad no se establecerá. */
}
}
Supported configurations: Las anotaciones de parámetro JAX-RS deben añadirse a los métodos de recursos en la interfaz empresarial EJB al utilizar interfaces empresariales.
No se pueden añadir al bean de implementación.
sptcfg
- Empaquete los enterprise beans en el directorio WEB-INF/classes del archivo WAR o en un archivo JAR
que se incluye en el directorio WEB-INF/lib del archivo WAR.
Cuando un cliente realiza una solicitud a un enterprise bean JAX-RS anotado, el entorno de ejecución JAX-RS busca y utiliza una instancia EJB de la
clase y, a continuación, invoca el método de recurso JAX-RS.
Resultados
Ha habilitado un enterprise bean existente con interfaces locales de modo que los recursos JAX-RS se exponen para el consumo.