EJB - Guía rápida
EJB significa Enterprise Java Beans. EJB es una parte esencial de una plataforma J2EE. La plataforma J2EE tiene una arquitectura basada en componentes para proporcionar características de múltiples niveles, distribuidas y altamente transaccionales a aplicaciones de nivel empresarial.
EJB proporciona una arquitectura para desarrollar e implementar aplicaciones empresariales basadas en componentes considerando la robustez, la alta escalabilidad y el alto rendimiento. Se puede implementar una aplicación EJB en cualquiera de los servidores de aplicaciones que cumplan con la especificación estándar J2EE 1.3.
Discutiremos EJB 3.0 en detalle en este tutorial.
Tipos
EJB se divide principalmente en tres categorías; La siguiente tabla enumera sus nombres con breves descripciones:
S. No | Tipo y descripción |
---|---|
1 | Session Bean El bean de sesión almacena datos de un usuario en particular para una sola sesión. Puede serstateful o stateless. Es menos intensivo en recursos en comparación con el bean de entidad. El bean de sesión se destruye tan pronto como termina la sesión del usuario. |
2 | Entity Bean Entity beansrepresentan el almacenamiento de datos persistentes. Los datos del usuario se pueden guardar en la base de datos a través de beans de entidad y luego se pueden recuperar de la base de datos en el bean de entidad. |
3 | Message Driven Bean Message driven beansse utilizan en el contexto de JMS (Java Messaging Service). Los beans controlados por mensajes pueden consumir mensajes JMS de entidades externas y actuar en consecuencia. |
Beneficios
Los siguientes son los beneficios importantes de EJB:
Desarrollo simplificado de aplicaciones de nivel empresarial a gran escala.
El contenedor Application Server / EJB proporciona la mayoría de los servicios a nivel del sistema, como el manejo de transacciones, el registro, el equilibrio de carga, el mecanismo de persistencia, el manejo de excepciones, etc. El desarrollador debe centrarse únicamente en la lógica empresarial de la aplicación.
El contenedor EJB administra el ciclo de vida de las instancias EJB, por lo que el desarrollador no debe preocuparse por cuándo crear / eliminar objetos EJB.
EJB es un marco para Java, por lo que el primer requisito es tener un Java Ddesarrollo Kit (JDK) instalado en su máquina.
Requisitos del sistema
JDK | 1,5 o superior. |
---|---|
Memoria | ningún requisito mínimo. |
Espacio del disco | ningún requisito mínimo. |
Sistema operativo | ningún requisito mínimo. |
Paso 1: verificar la instalación de Java en su sistema
Ahora abra la consola y ejecute lo siguiente java mando.
SO | Tarea | Mando |
---|---|---|
Ventanas | Abrir consola de comandos | c: \> java -version |
Linux | Terminal de comando abierto | $ java -version |
Mac | Terminal abierta | máquina: ~ joseph $ java -version |
Verifiquemos la salida para todos los sistemas operativos:
SO | Salida |
---|---|
Ventanas | versión de Java "1.6.0_21" Entorno de ejecución Java (TM) SE (compilación 1.6.0_21-b11) Servidor VM Java HotSpot (TM) de 64 bits (compilación 23.21-b01, modo mixto) |
Linux | versión de Java "1.6.0_21" Entorno de ejecución Java (TM) SE (compilación 1.6.0_21-b11) Servidor VM Java HotSpot (TM) de 64 bits (compilación 23.21-b01, modo mixto) |
Mac | versión de Java "1.6.0_21" Entorno de ejecución Java (TM) SE (compilación 1.6.0_21-b11) Servidor VM Java HotSpot (TM) de 64 bits (compilación 23.21-b01, modo mixto) |
Si no tiene Java instalado, instale Java Software Development Kit (SDK) de www.oracle.com . Suponemos que Java 1.6.0_21 es la versión instalada para este tutorial.
Paso 2: configurar el entorno JAVA
Selecciona el JAVA_HOMEvariable de entorno para señalar la ubicación del directorio base donde está instalado Java en su sistema. Por ejemplo,
SO | Salida |
---|---|
Ventanas | Establezca la variable de entorno JAVA_HOME en C: \ Archivos de programa \ Java \ jdk1.6.0_21 |
Linux | exportar JAVA_HOME = / usr / local / java-current |
Mac | exportar JAVA_HOME = / Library / Java / Home |
Agregue la ubicación del compilador de Java a la ruta del sistema.
SO | Salida |
---|---|
Ventanas | Agregue la cadena; C: \ Archivos de programa \ Java \ jdk1.6.0_21 \ bin al final de la variable del sistema, Ruta. |
Linux | export PATH =$PATH:$JAVA_HOME / bin / |
Mac | no requerido |
Verifique la instalación de Java usando java -version comando explicado anteriormente.
Paso 3: descargue e instale NetBeans IDE
Descargue la última versión de NetBeans IDE de netbeans.org . En el momento de escribir este tutorial, descargué Netbeans 7.3 que viene incluido con JDK 1.7 usando el siguiente enlace www.oracle.com
SO | Nombre del instalador |
---|---|
Ventanas | Netbeans 7.3 |
Linux | Netbeans 7.3 |
Mac | Netbeans 7.3 |
Paso 4: configurar el servidor de aplicaciones JBoss
Puede descargar la última versión de JBoss Server desde www.jboss.org . Descargue el archivo según la plataforma. Extraiga el Jboss a cualquier ubicación de su máquina.
SO | Nombre del archivo |
---|---|
Ventanas | jboss-5.1.0.GA-jdk6.zip |
Linux | jboss-5.1.0.GA-src.tar.gz |
Mac | jboss-5.1.0.GA-src.tar.gz |
Paso 5: configurar complementos JEE para Netbeans
Abra la ventana Complemento usando Herramientas> Complementos. Abra la pestaña "Complemento disponible" y seleccione "Java EE Base" y "EJB y EAR" en la categoría "Java Web y EE". Haga clic en el botón de instalación. Netbeans descargará e instalará los complementos respectivos. Verifique la instalación de los complementos usando la pestaña "Instalado" (como se muestra en la imagen que se muestra a continuación).
Paso 6: configurar el servidor JBoss en Netbeans
Vaya a la pestaña Servicios y haga clic derecho en los servidores para agregar un nuevo servidor.
Se abrirá el asistente Agregar instancia de servidor. Seleccione JBoss y en el siguiente paso ingrese los detalles relevantes para configurar el servidor en netbeans.
Una vez que todo esté configurado, verá la siguiente pantalla.
Paso 7: instalar el servidor de base de datos (PostGreSql)
Descargue la última versión del servidor de base de datos PostGreSql desde www.postgresql.org . En el momento de escribir este tutorial, descargué PostGreSql 9.2
SO | Nombre del instalador |
---|---|
Ventanas | PostGreSql 9.2 |
Linux | PostGreSql 9.2 |
Mac | PostGreSql 9.2 |
Para crear un módulo EJB simple, usaremos NetBeans, el asistente "Nuevo proyecto". En el ejemplo que se muestra a continuación, crearemos un proyecto de módulo EJB llamado Component.
Crear proyecto
En NetBeans IDE, seleccione File > New Project >. Verá la siguiente pantalla
Seleccione el tipo de proyecto en la categoría Java EE, Tipo de proyecto como EJB Module. Hacer clicNext >botón. Verá la siguiente pantalla.
Ingrese el nombre y la ubicación del proyecto. Hacer clicNext >botón. Verá la siguiente pantalla.
Seleccionar servidor como JBoss Application Server. Hacer clicFinishbotón. Verá el siguiente proyecto creado por NetBeans.
Crear un EJB de muestra
Para crear un EJB simple, usaremos el asistente "Nuevo" de NetBeans. En el ejemplo que se muestra a continuación, crearemos una clase EJB sin estado llamada librarySessionBean en el proyecto EjbComponent.
Seleccione el proyecto EjbComponent en la ventana del explorador de proyectos y haga clic derecho sobre él. Seleccione,New > Session Bean. Verás elNew Session Bean mago.
Introduzca el nombre del bean de sesión y el nombre del paquete. Hacer clicFinishbotón. Verá las siguientes clases EJB creadas por NetBeans.
LibrarySessionBean - bean de sesión sin estado
LibrarySessionBeanLocal - interfaz local para el bean de sesión
Estoy cambiando la interfaz local a la interfaz remota ya que vamos a acceder a nuestro EJB en una aplicación basada en consola. La interfaz remota / local se utiliza para exponer los métodos comerciales que debe implementar un EJB.
LibrarySessionBeanLocal se renombra a LibrarySessionBeanRemote y LibrarySessionBean implementa la interfaz LibrarySessionBeanRemote.
LibrarySessionBeanRemote
package com.tutorialspoint.stateless;
import java.util.List;
import javax.ejb.Remote;
@Remote
public interface LibrarySessionBeanRemote {
void addBook(String bookName);
List getBooks();
}
LibrarySessionBean
package com.tutorialspoint.stateless;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;
@Stateless
public class LibrarySessionBean implements LibrarySessionBeanRemote {
List<String> bookShelf;
public LibrarySessionBean() {
bookShelf = new ArrayList<String>();
}
public void addBook(String bookName) {
bookShelf.add(bookName);
}
public List<String> getBooks() {
return bookShelf;
}
}
Construye el Proyecto
- Seleccione el proyecto EjbComponent en la ventana Explorador de proyectos.
- Haga clic derecho sobre él para abrir el menú contextual.
- Seleccione limpiar y construir.
Verá la siguiente salida en la salida de la consola NetBeans.
ant -f C:\\EJB\\EjbComponent clean dist
init:
undeploy-clean:
deps-clean:
Deleting directory C:\EJB\EjbComponent\build
Deleting directory C:\EJB\EjbComponent\dist
clean:
init:
deps-jar:
Created dir: C:\EJB\EjbComponent\build\classes
Copying 3 files to C:\EJB\EjbComponent\build\classes\META-INF
Created dir: C:\EJB\EjbComponent\build\empty
Created dir: C:\EJB\EjbComponent\build\generated-sources\ap-source-output
Compiling 2 source files to C:\EJB\EjbComponent\build\classes
warning: [options] bootstrap class path not set in conjunction with -source 1.6
Note: C:\EJB\EjbComponent\src\java\com\tutorialspoint\stateless
\LibraryPersistentBean.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 warning
compile:
library-inclusion-in-archive:
Created dir: C:\EJB\EjbComponent\dist
Building jar: C:\EJB\EjbComponent\dist\EjbComponent.jar
dist:
BUILD SUCCESSFUL (total time: 3 seconds)
Inicie el servidor de aplicaciones
- Seleccione el servidor de aplicaciones JBoss en la ventana Servidores en Servicios.
- Haga clic derecho sobre él para abrir el menú contextual.
- Seleccione iniciar.
Verá la siguiente salida en NetBeans, salida en JBoss Application Server.
Calling C:\jboss-5.1.0.GA\bin\run.conf.bat
=========================================================================
JBoss Bootstrap Environment
JBOSS_HOME: C:\jboss-5.1.0.GA
JAVA: C:\Program Files (x86)\Java\jdk1.6.0_21\bin\java
JAVA_OPTS: -Dprogram.name=run.bat -Xms128m -Xmx512m -server
CLASSPATH: C:\jboss-5.1.0.GA\bin\run.jar
=========================================================================
16:25:50,062 INFO [ServerImpl] Starting JBoss (Microcontainer)...
16:25:50,062 INFO [ServerImpl] Release ID: JBoss
[The Oracle] 5.1.0.GA (build: SVNTag=JBoss_5_1_0_GA date=200905221634)
...
16:26:40,420 INFO [TomcatDeployment] deploy, ctxPath=/admin-console
16:26:40,485 INFO [config] Initializing Mojarra (1.2_12-b01-FCS) for context '/admin-console'
16:26:42,362 INFO [TomcatDeployment] deploy, ctxPath=/
16:26:42,406 INFO [TomcatDeployment] deploy, ctxPath=/jmx-console
16:26:42,471 INFO [Http11Protocol] Starting Coyote HTTP/1.1 on http-127.0.0.1-8080
16:26:42,487 INFO [AjpProtocol] Starting Coyote AJP/1.3 on ajp-127.0.0.1-8009
16:26:42,493 INFO [ServerImpl] JBoss (Microcontainer)
[5.1.0.GA (build: SVNTag=JBoss_5_1_0_GA date=200905221634)] Started in 52s:427ms
Implementar el proyecto
- Seleccione el proyecto EjbComponent en la ventana Explorador de proyectos.
- Haga clic derecho sobre él para abrir el menú contextual.
- Seleccione Implementar.
Verá la siguiente salida en la salida de la consola NetBeans.
ant -f C:\\EJB\\EjbComponent -DforceRedeploy=true -Ddirectory.deployment.supported=false -Dnb.wait.for.caches=true run
init:
deps-jar:
compile:
library-inclusion-in-archive:
Building jar: C:\EJB\EjbComponent\dist\EjbComponent.jar
dist-directory-deploy:
pre-run-deploy:
Checking data source definitions for missing JDBC drivers...
Distributing C:\EJB\EjbComponent\dist\EjbComponent.jar to [org.jboss.deployment.spi.LocalhostTarget@1e4f84ee]
Deploying C:\EJB\EjbComponent\dist\EjbComponent.jar
Application Deployed
Operation start started
Operation start completed
post-run-deploy:
run-deploy:
run:
BUILD SUCCESSFUL (total time: 2 seconds)
Salida de registro del servidor de aplicaciones JBoss
16:30:00,963 INFO [DeployHandler] Begin start, [EjbComponent.jar]
...
16:30:01,233 INFO [Ejb3DependenciesDeployer] Encountered deployment AbstractVFSDeploymentContext@12038795{vfszip:/C:/jboss-5.1.0.GA/server/default/deploy/EjbComponent.jar/}
...
16:30:01,281 INFO [JBossASKernel] jndi:LibrarySessionBean/remote-com.tutorialspoint.stateless.LibrarySessionBeanRemote
16:30:01,281 INFO [JBossASKernel] Class:com.tutorialspoint.stateless.LibrarySessionBeanRemote
16:30:01,281 INFO [JBossASKernel] jndi:LibrarySessionBean/remote
16:30:01,281 INFO [JBossASKernel] Added bean(jboss.j2ee:jar=EjbComponent.jar,name=
LibrarySessionBean,service=EJB3) to KernelDeployment of: EjbComponent.jar
16:30:01,282 INFO [JBossASKernel] installing bean: jboss.j2ee:jar=EjbComponent.jar,name=BookMessageHandler,service=EJB3
16:30:01,282 INFO [JBossASKernel] with dependencies:
16:30:01,282 INFO [JBossASKernel] and demands:
16:30:01,282 INFO [JBossASKernel] jboss.ejb:service=EJBTimerService
...
16:30:01,283 INFO [EJB3EndpointDeployer] Deploy
AbstractBeanMetaData@5497cb{name=jboss.j2ee:jar=EjbComponent.jar,
name=LibrarySessionBean, service=EJB3_endpoint bean=org.jboss.ejb3.endpoint.deployers.impl.EndpointImpl properties=[container] constructor=null autowireCandidate=true}
...
16:30:01,394 INFO [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibrarySessionBean,service=EJB3
16:30:01,395 INFO [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibrarySessionBean ejbName: LibrarySessionBean
16:30:01,401 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
LibrarySessionBean/remote - EJB3.x Default Remote Business Interface
LibrarySessionBean/remote-com.tutorialspoint.stateless.LibrarySessionBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibrarySessionBean,service=EJB3
16:30:02,723 INFO [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibrarySessionBean ejbName: LibrarySessionBean
16:30:02,731 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
LibrarySessionBean/remote - EJB3.x Default Remote Business Interface
LibrarySessionBean/remote-com.tutorialspoint.stateless.LibrarySessionBeanRemote - EJB3.x Remote Business Interface
Crear cliente para acceder a EJB
En NetBeans IDE, seleccione File > New Project >.
Seleccione el tipo de proyecto en la categoría Java, Tipo de proyecto como Java Application. Haga clic en el botón Siguiente>
Ingrese el nombre y la ubicación del proyecto. Hacer clicFinish >botón. Hemos elegido el nombre EjbTester.
Haga clic derecho en el nombre del proyecto en la ventana del Explorador de proyectos. Seleccioneproperties.
Agregue el proyecto de componente EJB creado anteriormente en bibliotecas usando Add Project botón en compile lengüeta.
Agregue bibliotecas jboss usando Add jar/folder botón en compilelengüeta. Las bibliotecas de Jboss se pueden ubicar en la <carpeta de instalación de jboss >> carpeta del cliente.
Cree jndi.properties bajo proyecto, digamos EjbTester.
jndi.properties
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
Cree el paquete com.tutorialspoint.test y la clase EJBTester.java debajo de él.
EJBTester.java
package com.tutorialspoint.test;
import com.tutorialspoint.stateless.LibrarySessionBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class EJBTester {
BufferedReader brConsoleReader = null;
Properties props;
InitialContext ctx;
{
props = new Properties();
try {
props.load(new FileInputStream("jndi.properties"));
} catch (IOException ex) {
ex.printStackTrace();
}
try {
ctx = new InitialContext(props);
} catch (NamingException ex) {
ex.printStackTrace();
}
brConsoleReader =
new BufferedReader(new InputStreamReader(System.in));
}
public static void main(String[] args) {
EJBTester ejbTester = new EJBTester();
ejbTester.testStatelessEjb();
}
private void showGUI() {
System.out.println("**********************");
System.out.println("Welcome to Book Store");
System.out.println("**********************");
System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
}
private void testStatelessEjb() {
try {
int choice = 1;
LibrarySessionBeanRemote libraryBean =
(LibrarySessionBeanRemote)ctx.lookup("LibrarySessionBean/remote");
while (choice != 2) {
String bookName;
showGUI();
String strChoice = brConsoleReader.readLine();
choice = Integer.parseInt(strChoice);
if (choice == 1) {
System.out.print("Enter book name: ");
bookName = brConsoleReader.readLine();
libraryBean.addBook(bookName);
}else if (choice == 2) {
break;
}
}
List<String> booksList = libraryBean.getBooks();
System.out.println("Book(s) entered so far: " + booksList.size());
for (int i = 0; i < booksList.size(); ++i) {
System.out.println((i+1)+". " + booksList.get(i));
}
LibrarySessionBeanRemote libraryBean1 =
(LibrarySessionBeanRemote)ctx.lookup("LibrarySessionBean/remote");
List<String> booksList1 = libraryBean1.getBooks();
System.out.println(
"***Using second lookup to get library stateless object***");
System.out.println(
"Book(s) entered so far: " + booksList1.size());
for (int i = 0; i < booksList1.size(); ++i) {
System.out.println((i+1)+". " + booksList1.get(i));
}
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
} finally {
try {
if(brConsoleReader !=null) {
brConsoleReader.close();
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}
}
Ejecute el cliente para acceder a EJB
Busque EJBTester.java en el explorador de proyectos. Haga clic derecho en la clase EJBTester y seleccionerun file.
Verifique la siguiente salida en la consola de Netbeans.
run:
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 1
Enter book name: Learn Java
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 2
Book(s) entered so far: 1
1. Learn Java
***Using second lookup to get library stateless object***
Book(s) entered so far: 0
BUILD SUCCESSFUL (total time: 13 seconds)
En los siguientes capítulos, cubriremos múltiples aspectos de esta completa aplicación EJB.
Un bean de sesión sin estado es un tipo de enterprise bean, que normalmente se utiliza para realizar operaciones independientes. Un bean de sesión sin estado según su nombre no tiene ningún estado de cliente asociado, pero puede conservar su estado de instancia. EJB Container normalmente crea un grupo de pocos objetos de bean sin estado y usa estos objetos para procesar la solicitud del cliente. Debido al grupo, no se garantiza que los valores de las variables de instancia sean los mismos en todas las búsquedas / llamadas a métodos.
Pasos para crear un EJB sin estado
Los siguientes son los pasos necesarios para crear un EJB sin estado:
Cree una interfaz remota / local que exponga los métodos comerciales.
Esta interfaz será utilizada por la aplicación cliente EJB.
Utilice la anotación @Local, si el cliente EJB se encuentra en el mismo entorno donde se desplegará el bean de sesión EJB.
Utilice la anotación @Remote, si el cliente EJB se encuentra en un entorno diferente donde se desplegará el bean de sesión EJB.
Cree un bean de sesión sin estado, implementando la interfaz anterior.
Utilice la anotación @Stateless para indicar que es un bean sin estado. EJB Container crea automáticamente las configuraciones o interfaces relevantes requeridas leyendo esta anotación durante la implementación.
Interfaz remota
import javax.ejb.Remote;
@Remote
public interface LibrarySessionBeanRemote {
//add business method declarations
}
EJB sin estado
@Stateless
public class LibrarySessionBean implements LibrarySessionBeanRemote {
//implement business method
}
Aplicación de ejemplo
Creemos una aplicación EJB de prueba para probar EJB sin estado.
Paso | Descripción |
---|---|
1 | Cree un proyecto con un nombre EjbComponent en un paquete com.tutorialspoint.stateless como se explica en el capítulo EJB - Crear aplicación . También puede utilizar el proyecto creado en el capítulo EJB - Crear aplicación como tal para que este capítulo comprenda los conceptos de EJB sin estado. |
2 | Cree LibrarySessionBean.java y LibrarySessionBeanRemote como se explica en el capítulo EJB - Crear aplicación . Mantenga el resto de los archivos sin cambios. |
3 | Limpie y compile la aplicación para asegurarse de que la lógica empresarial funcione según los requisitos. |
4 | Finalmente, implemente la aplicación en forma de archivo jar en JBoss Application Server. El servidor de aplicaciones JBoss se iniciará automáticamente si aún no se ha iniciado. |
5 | Ahora cree el cliente EJB, una aplicación basada en consola de la misma manera que se explica en el capítulo EJB - Crear aplicación en el temaCreate Client to access EJB. |
EJBComponent (módulo EJB)
LibrarySessionBeanRemote.java
package com.tutorialspoint.stateless;
import java.util.List;
import javax.ejb.Remote;
@Remote
public interface LibrarySessionBeanRemote {
void addBook(String bookName);
List getBooks();
}
LibrarySessionBean.java
package com.tutorialspoint.stateless;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;
@Stateless
public class LibrarySessionBean implements LibrarySessionBeanRemote {
List<String> bookShelf;
public LibrarySessionBean() {
bookShelf = new ArrayList<String>();
}
public void addBook(String bookName) {
bookShelf.add(bookName);
}
public List<String> getBooks() {
return bookShelf;
}
}
Tan pronto como implemente el proyecto EjbComponent en JBOSS, observe el registro de jboss.
JBoss ha creado automáticamente una entrada JNDI para nuestro bean de sesión - LibrarySessionBean/remote.
Usaremos esta cadena de búsqueda para obtener un objeto comercial remoto de tipo: com.tutorialspoint.stateless.LibrarySessionBeanRemote
Salida de registro del servidor de aplicaciones JBoss
...
16:30:01,401 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
LibrarySessionBean/remote - EJB3.x Default Remote Business Interface
LibrarySessionBean/remote-com.tutorialspoint.stateless.LibrarySessionBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibrarySessionBean,service=EJB3
16:30:02,723 INFO [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibrarySessionBeanRemote ejbName: LibrarySessionBean
16:30:02,731 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
LibrarySessionBean/remote - EJB3.x Default Remote Business Interface
LibrarySessionBean/remote-com.tutorialspoint.stateless.LibrarySessionBeanRemote - EJB3.x Remote Business Interface
...
EJBTester (cliente EJB)
jndi.properties
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
Estas propiedades se utilizan para inicializar el objeto InitialContext del servicio de nombres de Java.
El objeto InitialContext se utilizará para buscar un bean de sesión sin estado.
EJBTester.java
package com.tutorialspoint.test;
import com.tutorialspoint.stateful.LibrarySessionBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class EJBTester {
BufferedReader brConsoleReader = null;
Properties props;
InitialContext ctx;
{
props = new Properties();
try {
props.load(new FileInputStream("jndi.properties"));
} catch (IOException ex) {
ex.printStackTrace();
}
try {
ctx = new InitialContext(props);
} catch (NamingException ex) {
ex.printStackTrace();
}
brConsoleReader =
new BufferedReader(new InputStreamReader(System.in));
}
public static void main(String[] args) {
EJBTester ejbTester = new EJBTester();
ejbTester.testStatelessEjb();
}
private void showGUI() {
System.out.println("**********************");
System.out.println("Welcome to Book Store");
System.out.println("**********************");
System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
}
private void testStatelessEjb() {
try {
int choice = 1;
LibrarySessionBeanRemote libraryBean =
LibrarySessionBeanRemote)ctx.lookup("LibrarySessionBean/remote");
while (choice != 2) {
String bookName;
showGUI();
String strChoice = brConsoleReader.readLine();
choice = Integer.parseInt(strChoice);
if (choice == 1) {
System.out.print("Enter book name: ");
bookName = brConsoleReader.readLine();
Book book = new Book();
book.setName(bookName);
libraryBean.addBook(book);
} else if (choice == 2) {
break;
}
}
List<Book> booksList = libraryBean.getBooks();
System.out.println("Book(s) entered so far: " + booksList.size());
int i = 0;
for (Book book:booksList) {
System.out.println((i+1)+". " + book.getName());
i++;
}
LibrarySessionBeanRemote libraryBean1 =
(LibrarySessionBeanRemote)ctx.lookup("LibrarySessionBean/remote");
List<String> booksList1 = libraryBean1.getBooks();
System.out.println(
"***Using second lookup to get library stateless object***");
System.out.println(
"Book(s) entered so far: " + booksList1.size());
for (int i = 0; i < booksList1.size(); ++i) {
System.out.println((i+1)+". " + booksList1.get(i));
}
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}finally {
try {
if(brConsoleReader !=null) {
brConsoleReader.close();
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}
}
EJBTester realiza las siguientes tareas:
Cargue las propiedades de jndi.properties e inicialice el objeto InitialContext.
En el método testStatelessEjb (), la búsqueda de jndi se realiza con el nombre - "LibrarySessionBean / remote" para obtener el objeto comercial remoto (ejb sin estado).
Luego, se muestra al usuario una interfaz de usuario de la tienda de la biblioteca y se le pide que ingrese la opción.
Si el usuario ingresa 1, el sistema solicita el nombre del libro y guarda el libro usando el método addBook () del bean de sesión sin estado. Session Bean está almacenando el libro en su variable de instancia.
Si el usuario ingresa 2, el sistema recupera libros usando el método getBooks () de bean de sesión sin estado y sale.
Luego, se realiza otra búsqueda de jndi con el nombre "LibrarySessionBean / remote" para obtener el objeto comercial remoto (EJB sin estado) nuevamente y se realiza la lista de libros.
Ejecute el cliente para acceder a EJB
Busque EJBTester.java en el explorador de proyectos. Haga clic derecho en la clase EJBTester y seleccionerun file.
Verifique la siguiente salida en la consola de Netbeans.
run:
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 1
Enter book name: Learn Java
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 2
Book(s) entered so far: 1
1. Learn Java
***Using second lookup to get library stateless object***
Book(s) entered so far: 0
BUILD SUCCESSFUL (total time: 13 seconds)
Ejecute el cliente de nuevo para acceder a EJB
Busque EJBTester.java en el explorador de proyectos. Haga clic derecho en la clase EJBTester y seleccionerun file.
Verifique la siguiente salida en la consola de Netbeans.
run:
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 2
Book(s) entered so far: 0
***Using second lookup to get library stateless object***
Book(s) entered so far: 1
1. Learn Java
BUILD SUCCESSFUL (total time: 12 seconds)
La salida que se muestra arriba puede variar, dependiendo de cuántos objetos EJB sin estado mantenga JBoss.
En caso de que se mantenga un único objeto EJB sin estado, es posible que vea la misma lista de libros después de cada búsqueda.
El contenedor EJB puede devolver el mismo objeto EJB sin estado para cada búsqueda.
El bean EJB sin estado mantiene el valor de la variable de instancia hasta que no se reinicia el servidor.
Un bean de sesión con estado es un tipo de bean empresarial que conserva el estado conversacional con el cliente. Un bean de sesión con estado según su nombre mantiene el estado del cliente asociado en sus variables de instancia. EJB Container crea un bean de sesión con estado independiente para procesar cada solicitud del cliente. Tan pronto como finaliza el alcance de la solicitud, se destruye el bean de sesión con estado.
Pasos para crear EJB con estado
Los siguientes son los pasos necesarios para crear un EJB con estado:
Cree una interfaz remota / local que exponga los métodos comerciales.
Esta interfaz será utilizada por la aplicación cliente EJB.
Utilice la anotación @Local si el cliente EJB está en el mismo entorno donde se debe implementar el bean de sesión EJB.
Utilice la anotación @Remote si el cliente EJB se encuentra en un entorno diferente donde se debe implementar el bean de sesión EJB.
Cree un bean de sesión con estado, implementando la interfaz anterior.
Utilice la anotación @Stateful para indicar que es un bean con estado. EJB Container crea automáticamente las configuraciones o interfaces relevantes requeridas leyendo esta anotación durante la implementación.
Interfaz remota
import javax.ejb.Remote;
@Remote
public interface LibraryStatefulSessionBeanRemote {
//add business method declarations
}
EJB con estado
@Stateful
public class LibraryStatefulSessionBean implements LibraryStatefulSessionBeanRemote {
//implement business method
}
Aplicación de ejemplo
Creemos una aplicación EJB de prueba para probar EJB con estado.
Paso | Descripción |
---|---|
1 | Cree un proyecto con un nombre EjbComponent en un paquete com.tutorialspoint.stateful como se explica en el capítulo EJB - Crear aplicación . También puede utilizar el proyecto creado en el capítulo EJB - Crear aplicación como tal para que este capítulo comprenda los conceptos de EJB con estado. |
2 | Cree LibraryStatefulSessionBean.java y LibraryStatefulSessionBeanRemote como se explica en el capítulo EJB - Crear aplicación . Mantenga el resto de los archivos sin cambios. |
3 | Limpie y compile la aplicación para asegurarse de que la lógica empresarial funcione según los requisitos. |
4 | Finalmente, implemente la aplicación en forma de archivo jar en JBoss Application Server. El servidor de aplicaciones JBoss se iniciará automáticamente si aún no se ha iniciado. |
5 | Ahora cree el cliente EJB, una aplicación basada en consola de la misma manera que se explica en el capítulo EJB - Crear aplicación en el temaCreate Client to access EJB. |
EJBComponent (módulo EJB)
LibraryStatefulSessionBeanRemote.java
package com.tutorialspoint.stateful;
import java.util.List;
import javax.ejb.Remote;
@Remote
public interface LibraryStatefulSessionBeanRemote {
void addBook(String bookName);
List getBooks();
}
LibraryStatefulSessionBean.java
package com.tutorialspoint.stateful;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateful;
@Stateful
public class LibraryStatefulSessionBean implements LibraryStatefulSessionBeanRemote {
List<String> bookShelf;
public LibraryStatefulSessionBean() {
bookShelf = new ArrayList<String>();
}
public void addBook(String bookName) {
bookShelf.add(bookName);
}
public List<String> getBooks() {
return bookShelf;
}
}
Tan pronto como implemente el proyecto EjbComponent en JBOSS, observe el registro de jboss.
JBoss ha creado automáticamente una entrada JNDI para nuestro bean de sesión - LibraryStatefulSessionBean/remote.
Usaremos esta cadena de búsqueda para obtener un objeto comercial remoto de tipo: com.tutorialspoint.stateful.LibraryStatefulSessionBeanRemote
Salida de registro del servidor de aplicaciones JBoss
...
16:30:01,401 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
LibraryStatefulSessionBean/remote - EJB3.x Default Remote Business Interface
LibraryStatefulSessionBean/remote-com.tutorialspoint.stateful.LibraryStatefulSessionBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryStatefulSessionBean,service=EJB3
16:30:02,723 INFO [EJBContainer] STARTED EJB: com.tutorialspoint.stateful.LibraryStatefulSessionBeanRemote ejbName: LibraryStatefulSessionBean
16:30:02,731 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
LibraryStatefulSessionBean/remote - EJB3.x Default Remote Business Interface
LibraryStatefulSessionBean/remote-com.tutorialspoint.stateful.LibraryStatefulSessionBeanRemote - EJB3.x Remote Business Interface
...
EJBTester (cliente EJB)
jndi.properties
java.naming.factory.initial = org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs = org.jboss.naming:org.jnp.interfaces
java.naming.provider.url = localhost
Estas propiedades se utilizan para inicializar el objeto InitialContext del servicio de nombres de Java.
El objeto InitialContext se utilizará para buscar un bean de sesión con estado.
EJBTester.java
package com.tutorialspoint.test;
import com.tutorialspoint.stateful.LibraryStatefulSessionBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class EJBTester {
BufferedReader brConsoleReader = null;
Properties props;
InitialContext ctx;
{
props = new Properties();
try {
props.load(new FileInputStream("jndi.properties"));
} catch (IOException ex) {
ex.printStackTrace();
}
try {
ctx = new InitialContext(props);
} catch (NamingException ex) {
ex.printStackTrace();
}
brConsoleReader =
new BufferedReader(new InputStreamReader(System.in));
}
public static void main(String[] args) {
EJBTester ejbTester = new EJBTester();
ejbTester.testStatelessEjb();
}
private void showGUI() {
System.out.println("**********************");
System.out.println("Welcome to Book Store");
System.out.println("**********************");
System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
}
private void testStatelessEjb() {
try {
int choice = 1;
LibraryStatefulSessionBeanRemote libraryBean =
LibraryStatefulSessionBeanRemote)ctx.lookup("LibraryStatefulSessionBean/remote");
while (choice != 2) {
String bookName;
showGUI();
String strChoice = brConsoleReader.readLine();
choice = Integer.parseInt(strChoice);
if (choice == 1) {
System.out.print("Enter book name: ");
bookName = brConsoleReader.readLine();
Book book = new Book();
book.setName(bookName);
libraryBean.addBook(book);
} else if (choice == 2) {
break;
}
}
List<Book> booksList = libraryBean.getBooks();
System.out.println("Book(s) entered so far: " + booksList.size());
int i = 0;
for (Book book:booksList) {
System.out.println((i+1)+". " + book.getName());
i++;
}
LibraryStatefulSessionBeanRemote libraryBean1 =
(LibraryStatefulSessionBeanRemote)ctx.lookup("LibraryStatefulSessionBean/remote");
List<String> booksList1 = libraryBean1.getBooks();
System.out.println(
"***Using second lookup to get library stateful object***");
System.out.println(
"Book(s) entered so far: " + booksList1.size());
for (int i = 0; i < booksList1.size(); ++i) {
System.out.println((i+1)+". " + booksList1.get(i));
}
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}finally {
try {
if(brConsoleReader !=null) {
brConsoleReader.close();
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}
}
EJBTester realiza las siguientes tareas:
Cargue las propiedades de jndi.properties e inicialice el objeto InitialContext.
En el método testStatefulEjb (), la búsqueda de jndi se realiza con el nombre - "LibraryStatefulSessionBean / remote" para obtener el objeto de negocio remoto (ejb con estado).
Luego, se muestra al usuario una interfaz de usuario de la tienda de la biblioteca y se le pide que ingrese una opción.
Si el usuario ingresa 1, el sistema solicita el nombre del libro y guarda el libro usando el método addBook () del bean de sesión con estado. Session Bean está almacenando el libro en su variable de instancia.
Si el usuario ingresa 2, el sistema recupera los libros usando el método getBooks () del bean de sesión con estado y sale.
Luego, se realiza otra búsqueda de jndi con el nombre - "LibraryStatefulSessionBean / remote" para obtener el objeto comercial remoto (EJB con estado) nuevamente y se realiza la lista de libros.
Ejecute el cliente para acceder a EJB
Busque EJBTester.java en el explorador de proyectos. Haga clic derecho en la clase EJBTester y seleccionerun file.
Verifique la siguiente salida en la consola de Netbeans:
run:
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 1
Enter book name: Learn Java
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 2
Book(s) entered so far: 1
1. Learn Java
***Using second lookup to get library stateful object***
Book(s) entered so far: 0
BUILD SUCCESSFUL (total time: 13 seconds)
Ejecute el cliente de nuevo para acceder a EJB
Busque EJBTester.java en el explorador de proyectos. Haga clic derecho en la clase EJBTester y seleccionerun file.
Verifique la siguiente salida en la consola de Netbeans.
run:
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 2
Book(s) entered so far: 0
***Using second lookup to get library stateful object***
Book(s) entered so far: 0
BUILD SUCCESSFUL (total time: 12 seconds)
El resultado que se muestra arriba indica que para cada búsqueda, se devuelve una instancia EJB con estado diferente.
El objeto EJB con estado conserva el valor solo para una sesión. Como en la segunda tirada, no obtenemos ningún valor por los libros.
EJB 3.0, el bean de entidad utilizado en EJB 2.0 se reemplaza en gran medida por el mecanismo de persistencia. Ahora, el bean de entidad es un POJO simple que tiene un mapeo con la tabla.
Los siguientes son los actores clave en la API de persistencia:
Entity- Un objeto persistente que representa el registro del almacén de datos. Es bueno ser serializable.
EntityManager- Interfaz de persistencia para realizar operaciones de datos como agregar / eliminar / actualizar / buscar en un objeto persistente (entidad). También ayuda a ejecutar consultas usandoQuery interfaz.
Persistence unit (persistence.xml) - Unidad de persistencia describe las propiedades del mecanismo de persistencia.
Data Source (*ds.xml)- Fuente de datos describe las propiedades relacionadas con el almacén de datos, como la URL de conexión. nombre de usuario, contraseña, etc.
Para demostrar el mecanismo de persistencia de EJB, debemos realizar las siguientes tareas:
Step 1 - Crear tabla en base de datos.
Step 2 - Crear clase de entidad correspondiente a la tabla.
Step 3 - Creación de fuente de datos y unidad de persistencia.
Step 4 - Cree un EJB sin estado que tenga una instancia de EntityManager.
Step 5- Actualización de EJB sin estado. Agregue métodos para agregar registros y obtener registros de la base de datos a través del administrador de entidades.
Step 6 - Un cliente de aplicación basado en consola accederá al EJB sin estado para conservar los datos en la base de datos.
Crear mesa
Crea una tabla books en la base de datos predeterminada postgres.
CREATE TABLE books (
id integer PRIMARY KEY,
name varchar(50)
);
Crear clase de entidad
//mark it entity using Entity annotation
//map table name using Table annotation
@Entity
@Table(name="books")
public class Book implements Serializable{
private int id;
private String name;
public Book() {
}
//mark id as primary key with autogenerated value
//map database column id with id field
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
@Column(name="id")
public int getId() {
return id;
}
...
}
Crear unidad de fuente de datos y persistencia
Fuente de datos (jboss-ds.xml)
<?xml version = "1.0" encoding = "UTF-8"?>
<datasources>
<local-tx-datasource>
<jndi-name>PostgresDS</jndi-name>
<connection-url>jdbc:postgresql://localhost:5432/postgres</connection-url>
<driver-class>org.postgresql.driver</driver-class>
<user-name>sa</user-name>
<password>sa</password>
<min-pool-size>5</min-pool-size>
<max-pool-size>20</max-pool-size>
<idle-timeout-minutes>5</idle-timeout-minutes>
</local-tx-datasource>
</datasources>
Unidad de persistencia (persistence.xml)
<persistence version = "1.0" xmlns = "http://java.sun.com/xml/ns/persistence" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name = "EjbComponentPU" transaction-type = "JTA">
<jta-data-source>java:/PostgresDS</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties/>
</persistence-unit>
<persistence-unit name = "EjbComponentPU2" transaction-type = "JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/PostgresDS</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
</persistence>
Crear EJB sin estado con una instancia EntityManager
@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
//pass persistence unit to entityManager.
@PersistenceContext(unitName="EjbComponentPU")
private EntityManager entityManager;
public void addBook(Book book) {
entityManager.persist(book);
}
public List<Book> getBooks() {
return entityManager.createQuery("From Books").getResultList();
}
...
}
Después de construir el módulo EJB, necesitamos un cliente para acceder al bean sin estado, que crearemos en la siguiente sección.
Aplicación de ejemplo
Creemos una aplicación EJB de prueba para probar el mecanismo de persistencia de EJB.
Paso | Descripción |
---|---|
1 | Cree un proyecto con un nombre EjbComponent en un paquete com.tutorialspoint.entity como se explica en el capítulo EJB - Crear aplicación . También puede utilizar el proyecto creado en el capítulo EJB - Crear aplicación como tal para este capítulo para comprender los conceptos de persistencia de EJB. |
2 | Cree Book.java en el paquete com.tutorialspoint.entity y modifíquelo como se muestra a continuación. |
3 | Cree LibraryPersistentBean.java y LibraryPersistentBeanRemote como se explica en los capítulos EJB - Crear aplicación y modifíquelos como se muestra a continuación. |
4 | Cree jboss-ds.xml enEjbComponent > setup carpeta y persistence.xml enEjbComponent > src > conf carpeta. Estas carpetas se pueden ver en la pestaña de archivos en Netbeans. Modifique estos archivos como se muestra arriba. |
5 | Limpie y compile la aplicación para asegurarse de que la lógica empresarial funcione según los requisitos. |
6 | Finalmente, implemente la aplicación en forma de archivo jar en JBoss Application Server. El servidor de aplicaciones JBoss se iniciará automáticamente si aún no se ha iniciado. |
7 | Ahora cree el cliente EJB, una aplicación basada en consola de la misma manera que se explica en el capítulo EJB - Crear aplicación en el temaCreate Client to access EJB. Modifíquelo como se muestra a continuación. |
EJBComponent (módulo EJB)
Book.java
package com.tutorialspoint.entity;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="books")
public class Book implements Serializable{
private int id;
private String name;
public Book() {
}
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
@Column(name="id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
LibraryPersistentBeanRemote.java
package com.tutorialspoint.stateless;
import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Remote;
@Remote
public interface LibraryPersistentBeanRemote {
void addBook(Book bookName);
List<Book> getBooks();
}
LibraryPersistentBean.java
package com.tutorialspoint.stateless;
import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
public LibraryPersistentBean() {
}
@PersistenceContext(unitName="EjbComponentPU")
private EntityManager entityManager;
public void addBook(Book book) {
entityManager.persist(book);
}
public List<Book> getBooks() {
return entityManager.createQuery("From Book").getResultList();
}
}
Tan pronto como implemente el proyecto EjbComponent en JBOSS, observe el registro de jboss.
JBoss ha creado automáticamente una entrada JNDI para nuestro bean de sesión - LibraryPersistentBean/remote.
Usaremos esta cadena de búsqueda para obtener un objeto comercial remoto de tipo: com.tutorialspoint.stateless.LibraryPersistentBeanRemote
Salida de registro del servidor de aplicaciones JBoss
...
16:30:01,401 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
LibraryPersistentBean/remote-com.tutorialspoint.stateless.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryPersistentBeanRemote,service=EJB3
16:30:02,723 INFO [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibraryPersistentBeanRemote ejbName: LibraryPersistentBean
16:30:02,731 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
LibraryPersistentBean/remote-com.tutorialspoint.stateless.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
...
EJBTester (cliente EJB)
jndi.properties
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
Estas propiedades se utilizan para inicializar el objeto InitialContext del servicio de nombres de Java.
El objeto InitialContext se utilizará para buscar un bean de sesión sin estado.
EJBTester.java
package com.tutorialspoint.test;
import com.tutorialspoint.stateless.LibraryPersistentBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class EJBTester {
BufferedReader brConsoleReader = null;
Properties props;
InitialContext ctx;
{
props = new Properties();
try {
props.load(new FileInputStream("jndi.properties"));
} catch (IOException ex) {
ex.printStackTrace();
}
try {
ctx = new InitialContext(props);
} catch (NamingException ex) {
ex.printStackTrace();
}
brConsoleReader =
new BufferedReader(new InputStreamReader(System.in));
}
public static void main(String[] args) {
EJBTester ejbTester = new EJBTester();
ejbTester.testEntityEjb();
}
private void showGUI() {
System.out.println("**********************");
System.out.println("Welcome to Book Store");
System.out.println("**********************");
System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
}
private void testEntityEjb() {
try {
int choice = 1;
LibraryPersistentBeanRemote libraryBean =
LibraryPersistentBeanRemote)ctx.lookup("LibraryPersistentBean/remote");
while (choice != 2) {
String bookName;
showGUI();
String strChoice = brConsoleReader.readLine();
choice = Integer.parseInt(strChoice);
if (choice == 1) {
System.out.print("Enter book name: ");
bookName = brConsoleReader.readLine();
Book book = new Book();
book.setName(bookName);
libraryBean.addBook(book);
} else if (choice == 2) {
break;
}
}
List<Book> booksList = libraryBean.getBooks();
System.out.println("Book(s) entered so far: " + booksList.size());
int i = 0;
for (Book book:booksList) {
System.out.println((i+1)+". " + book.getName());
i++;
}
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}finally {
try {
if(brConsoleReader !=null) {
brConsoleReader.close();
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}
}
EJBTester realiza las siguientes tareas.
Cargue las propiedades de jndi.properties e inicialice el objeto InitialContext.
En el método testStatefulEjb (), la búsqueda de jndi se realiza con el nombre - "LibraryStatefulSessionBean / remote" para obtener el objeto de negocio remoto (ejb con estado).
Luego, se muestra al usuario una interfaz de usuario de la tienda de la biblioteca y se le pide que ingrese la opción.
Si el usuario ingresa 1, el sistema solicita el nombre del libro y guarda el libro usando el método addBook () del bean de sesión sin estado. Session Bean mantiene el libro en la base de datos a través de la llamada EntityManager.
Si el usuario ingresa 2, el sistema recupera los libros usando el método getBooks () del bean de sesión con estado y sale.
Luego, se realiza otra búsqueda de jndi con el nombre - "LibraryStatelessSessionBean / remote" para obtener el objeto comercial remoto (EJB sin estado) nuevamente y se realiza la lista de libros.
Ejecute el cliente para acceder a EJB
Busque EJBTester.java en el explorador de proyectos. Haga clic derecho en la clase EJBTester y seleccionerun file.
Verifique la siguiente salida en la consola de Netbeans:
run:
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 1
Enter book name: Learn Java
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 2
Book(s) entered so far: 1
1. learn java
BUILD SUCCESSFUL (total time: 15 seconds)
Ejecute el cliente de nuevo para acceder a EJB
Reinicie JBoss antes de acceder a EJB.
Busque EJBTester.java en el explorador de proyectos. Haga clic derecho en la clase EJBTester y seleccionerun file.
Verifique la siguiente salida en la consola de Netbeans.
run:
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 1
Enter book name: Learn Spring
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 2
Book(s) entered so far: 2
1. learn java
2. Learn Spring
BUILD SUCCESSFUL (total time: 15 seconds)
La salida que se muestra arriba indica que los libros se almacenan en almacenamiento persistente y se recuperan de la base de datos.
Un bean controlado por mensajes es un tipo de enterprise bean, que es invocado por el contenedor EJB cuando recibe un mensaje de una cola o un tema. El bean controlado por mensajes es un bean sin estado y se utiliza para realizar tareas de forma asíncrona.
Para demostrar el uso del bean controlado por mensajes, haremos uso del capítulo de persistencia EJB y debemos realizar las siguientes tareas:
Step 1- Crear tabla en la base de datos (consulte el capítulo EJB-Persistencia ).
Step 2- Cree la clase de entidad correspondiente a la tabla (consulte el capítulo EJB-Persistencia ).
Step 3- Crear fuente de datos y unidad de persistencia (consulte el capítulo EJB-Persistencia ).
Step 4- Cree un EJB sin estado que tenga una instancia de EntityManager (consulte el capítulo EJB-Persistencia ).
Step 5- Actualice los métodos ejb.Add sin estado para agregar registros y obtener registros de la base de datos a través del administrador de entidades (consulte el capítulo EJB-Persistencia ).
Step 6 - Crea una cola llamada BookQueue en JBoss default directorio de la aplicación.
Step 7 - Un cliente de aplicación basado en consola enviará un mensaje a esta cola.
Step 8 - Cree un bean controlado por mensajes, que utilizará el bean sin estado para conservar los datos del cliente.
Step 9 - El contenedor EJB de jboss llamará al bean controlado por mensaje anterior y le pasará el mensaje que el cliente enviará.
Crear cola
Cree un archivo llamado jbossmq-destinos-service.xml si no existe en <JBoss Installation Folder> > server > default > deploy carpeta.
Aquí estamos creando una cola llamada BookQueue -
jbossmq-destinos-service.xml
<mbean code="org.jboss.mq.server.jmx.Queue"
name="jboss.mq.destination:service=Queue,name=BookQueue">
<depends optional-attribute-name="DestinationManager">
jboss.mq:service=DestinationManager
</depends>
</mbean>
Cuando inicie JBoss, verá una entrada similar en el registro de jboss.
...
10:37:06,167 INFO [QueueService] Queue[/queue/BookQueue] started, fullSize=200000, pageSize=2000, downCacheSize=2000
...
Crear bean basado en mensajes
@MessageDriven(
name = "BookMessageHandler",
activationConfig = {
@ActivationConfigProperty( propertyName = "destinationType",
propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty( propertyName = "destination",
propertyValue ="/queue/BookQueue")
}
)
public class LibraryMessageBean implements MessageListener {
@Resource
private MessageDrivenContext mdctx;
@EJB
LibraryPersistentBeanRemote libraryBean;
public LibraryMessageBean() {
}
public void onMessage(Message message) {
}
}
LibraryMessageBean está anotado con la anotación @MessageDriven para marcarlo como bean controlado por mensajes.
Sus propiedades se definen como destinationType - Queue and destination - / queue / BookQueue.
Implementa la interfaz MessageListener, que expone el método onMessage.
Tiene MessgeDrivenContext como recurso.
El bean sin estado LibraryPersistentBeanRemote se inyecta en este bean para fines de persistencia.
Cree el proyecto EjbComponent e impleméntelo en JBoss. Después de construir e implementar el módulo EJB, necesitamos un cliente para enviar un mensaje a la cola de jboss.
Aplicación de ejemplo
Creemos una aplicación EJB de prueba para probar Message Driven Bean.
Paso | Descripción |
---|---|
1 | Cree un proyecto con un nombre EjbComponent en un paquete com.tutorialspoint.entity como se explica en el capítulo EJB - Crear aplicación . También puede utilizar el proyecto creado en el capítulo EJB - Crear aplicación como tal para este capítulo para comprender los conceptos de persistencia de EJB. |
2 | Cree Book.java en el paquete com.tutorialspoint.entity como se creó en el capítulo EJB-Persistence . |
3 | Cree LibraryPersistentBean.java y LibraryPersistentBeanRemote como se creó en el capítulo EJB-Persistence . |
4 | Cree jboss-ds.xml enEjbComponent > setup carpeta y persistence.xml enEjbComponent > src > conf carpeta. Estas carpetas se pueden ver en la pestaña de archivos en Netbeans como se creó en el capítulo EJB-Persistence . |
5 | Cree LibraryMessageBean.java en un paquete com.tutorialspoint.messagebean y modifíquelo como se muestra a continuación. |
6 | Crear BookQueue cola en Jboss como se describe anteriormente. |
7 | Limpie y compile la aplicación para asegurarse de que la lógica empresarial funcione según los requisitos. |
8 | Finalmente, implemente la aplicación en forma de archivo jar en JBoss Application Server. El servidor de aplicaciones JBoss se iniciará automáticamente si aún no se ha iniciado. |
9 | Ahora cree el cliente EJB, una aplicación basada en consola de la misma manera que se explica en el capítulo EJB - Crear aplicación en el temaCreate Client to access EJB. Modifíquelo como se muestra a continuación. |
EJBComponent (módulo EJB)
LibraryMessageBean.java
package com.tutorialspoint.messagebean;
import com.tutorialspoint.entity.Book;
import com.tutorialspoint.stateless.LibraryPersistentBeanRemote;
import javax.annotation.Resource;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.EJB;
import javax.ejb.MessageDriven;
import javax.ejb.MessageDrivenContext;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
@MessageDriven(
name = "BookMessageHandler",
activationConfig = {
@ActivationConfigProperty( propertyName = "destinationType",
propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty( propertyName = "destination",
propertyValue ="/queue/BookQueue")
}
)
public class LibraryMessageBean implements MessageListener {
@Resource
private MessageDrivenContext mdctx;
@EJB
LibraryPersistentBeanRemote libraryBean;
public LibraryMessageBean() {
}
public void onMessage(Message message) {
ObjectMessage objectMessage = null;
try {
objectMessage = (ObjectMessage) message;
Book book = (Book) objectMessage.getObject();
libraryBean.addBook(book);
} catch (JMSException ex) {
mdctx.setRollbackOnly();
}
}
}
EJBTester (cliente EJB)
EJBTester.java
package com.tutorialspoint.test;
import com.tutorialspoint.entity.Book;
import com.tutorialspoint.stateless.LibraryPersistentBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class EJBTester {
BufferedReader brConsoleReader = null;
Properties props;
InitialContext ctx;
{
props = new Properties();
try {
props.load(new FileInputStream("jndi.properties"));
} catch (IOException ex) {
ex.printStackTrace();
}
try {
ctx = new InitialContext(props);
} catch (NamingException ex) {
ex.printStackTrace();
}
brConsoleReader =
new BufferedReader(new InputStreamReader(System.in));
}
public static void main(String[] args) {
EJBTester ejbTester = new EJBTester();
ejbTester.testMessageBeanEjb();
}
private void showGUI() {
System.out.println("**********************");
System.out.println("Welcome to Book Store");
System.out.println("**********************");
System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
}
private void testMessageBeanEjb() {
try {
int choice = 1;
Queue queue = (Queue) ctx.lookup("/queue/BookQueue");
QueueConnectionFactory factory =
(QueueConnectionFactory) ctx.lookup("ConnectionFactory");
QueueConnection connection = factory.createQueueConnection();
QueueSession session =
connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
QueueSender sender = session.createSender(queue);
while (choice != 2) {
String bookName;
showGUI();
String strChoice = brConsoleReader.readLine();
choice = Integer.parseInt(strChoice);
if (choice == 1) {
System.out.print("Enter book name: ");
bookName = brConsoleReader.readLine();
Book book = new Book();
book.setName(bookName);
ObjectMessage objectMessage =
session.createObjectMessage(book);
sender.send(objectMessage);
} else if (choice == 2) {
break;
}
}
LibraryPersistentBeanRemote libraryBean =
(LibraryPersistentBeanRemote)
ctx.lookup("LibraryPersistentBean/remote");
List<Book> booksList = libraryBean.getBooks();
System.out.println("Book(s) entered so far: " + booksList.size());
int i = 0;
for (Book book:booksList) {
System.out.println((i+1)+". " + book.getName());
i++;
}
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}finally {
try {
if(brConsoleReader !=null) {
brConsoleReader.close();
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}
}
EJBTester realiza las siguientes tareas:
Cargue las propiedades de jndi.properties e inicialice el objeto InitialContext.
En el método testStatefulEjb (), la búsqueda de jndi se realiza con el nombre - "/ queue / BookQueue" para obtener la referencia de la cola disponible en Jboss. Luego, el remitente se crea usando la sesión de cola.
Luego, se muestra al usuario una interfaz de usuario de la tienda de la biblioteca y se le pide que ingrese la opción.
Si el usuario ingresa 1, el sistema solicita el nombre del libro y el remitente envía el nombre del libro a la cola. Cuando el contenedor JBoss recibe este mensaje en la cola, llama al método onMessage de nuestro bean controlado por mensajes. Nuestro bean controlado por mensajes luego guarda el libro usando el método addBook () del bean de sesión con estado. Session Bean mantiene el libro en la base de datos a través de la llamada EntityManager.
Si el usuario ingresa 2, entonces se realiza otra búsqueda jndi con el nombre - "LibraryStatefulSessionBean / remote" para obtener el objeto comercial remoto (EJB con estado) nuevamente y se realiza la lista de libros.
Ejecute el cliente para acceder a EJB
Busque EJBTester.java en el explorador de proyectos. Haga clic derecho en la clase EJBTester y seleccionerun file.
Verifique la siguiente salida en la consola de Netbeans:
run:
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 1
Enter book name: Learn EJB
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 2
Book(s) entered so far: 2
1. learn java
1. learn EJB
BUILD SUCCESSFUL (total time: 15 seconds)
El resultado que se muestra arriba indica que nuestro bean controlado por mensajes está recibiendo el mensaje y almacenando el libro en almacenamiento persistente y los libros se recuperan de la base de datos.
Las anotaciones se introdujeron en Java 5.0. El propósito de tener anotaciones es adjuntar información adicional en la clase o metadatos de una clase dentro de su código fuente. En EJB 3.0, las anotaciones se utilizan para describir los metadatos de configuración en las clases de EJB. De esta manera, EJB 3.0 elimina la necesidad de describir datos de configuración en archivos XML de configuración.
El contenedor EJB utiliza una herramienta de compilación para generar los artefactos necesarios, como interfaces, descriptores de implementación, leyendo esas anotaciones. A continuación se muestra la lista de anotaciones de uso común.
No Señor | Nombre | Descripción |
---|---|---|
1 | javax.ejb.Stateless |
Especifica que una clase EJB determinada es un bean de sesión sin estado. Attributes
|
2 | javax.ejb.Stateful |
Especifica que una clase EJB determinada es un bean de sesión con estado. Attributes
|
3 | javax.ejb.MessageDrivenBean |
Especifica que una clase EJB determinada es un bean controlado por mensajes. Attributes
|
4 | javax.ejb.EJB |
Se utiliza para especificar o inyectar una dependencia como instancia de EJB en otro EJB. Attributes
|
5 | javax.ejb.Local |
Se utiliza para especificar las interfaces locales de un bean de sesión. Esta interfaz local establece los métodos comerciales del bean de sesión (que puede ser sin estado o con estado). Esta interfaz se utiliza para exponer los métodos comerciales a los clientes locales, que se ejecutan en la misma implementación / aplicación que EJB. Attributes
|
6 | javax.ejb.Remote |
Se utiliza para especificar interfaces remotas de un bean de sesión. Esta interfaz remota establece los métodos comerciales del bean de sesión (que puede ser sin estado o con estado). Esta interfaz se utiliza para exponer los métodos comerciales a clientes remotos, que se ejecutan en diferentes implementaciones / aplicaciones como EJB. Attributes
|
7 | javax.ejb.Activation ConfigProperty |
Se utiliza para especificar las propiedades necesarias para un bean controlado por mensajes. Por ejemplo, punto final, destino, selector de mensajes, etc. Esta anotación se pasa como parámetro al atributo ActivaciónConfig de la anotación javax.ejb.MessageDrivenBean. Attributes
|
8 | javax.ejb.PostActivate |
Se utiliza para especificar el método de devolución de llamada del ciclo de vida de EJB. Se llamará a este método cuando el contenedor EJB haya activado / reactivado la instancia del bean. Esta interfaz se utiliza para exponer los métodos comerciales a los clientes locales, que se ejecutan en la misma implementación / aplicación que EJB. |
La devolución de llamada es un mecanismo mediante el cual se puede interceptar el ciclo de vida de un bean empresarial. La especificación EJB 3.0 ha especificado devoluciones de llamada para las que se crean métodos de manejo de devolución de llamada. EJB Container llama a estas devoluciones de llamada. Podemos definir métodos de devolución de llamada en la propia clase EJB o en una clase separada. EJB 3.0 ha proporcionado muchas anotaciones para devoluciones de llamada.
A continuación se muestra la lista de anotaciones de devolución de llamada para el bean sin estado:
Anotación | Descripción |
---|---|
@PostConstruct | Se invoca cuando se crea un bean por primera vez. |
@Predestroy | Se invoca cuando un frijol se elimina del grupo de frijoles o se destruye. |
A continuación se muestra la lista de anotaciones de devolución de llamada para el bean con estado:
Anotación | Descripción |
---|---|
@PostConstruct | Se invoca cuando se crea un bean por primera vez. |
@Predestroy | Se invoca cuando un frijol se elimina del grupo de frijoles o se destruye. |
@PostActivate | Se invoca cuando se carga un bean para su uso. |
@PrePassivate | Se invoca cuando un bean se devuelve al grupo de beans. |
A continuación se muestra la lista de anotaciones de devolución de llamada para el bean controlado por mensajes:
Anotación | Descripción |
---|---|
@PostConstruct | Se invoca cuando se crea un bean por primera vez. |
@Predestroy | Se invoca cuando un frijol se elimina del grupo de frijoles o se destruye. |
A continuación se muestra la lista de anotaciones de devolución de llamada para el bean de entidad:
Anotación | Descripción |
---|---|
@PrePersist | Se invoca cuando se crea una entidad en la base de datos. |
@PostPersist | Se invoca después de que se crea una entidad en la base de datos. |
@PreQuitar | Se invoca cuando se elimina una entidad de la base de datos. |
@PostRemove | Se invoca después de que se elimina una entidad de la base de datos. |
@PreUpdate | Se invoca antes de que una entidad se actualice en la base de datos. |
@PostLoad | Se invoca cuando se obtiene un registro de la base de datos y se carga en la entidad. |
Aplicación de ejemplo
Creemos una aplicación EJB de prueba para probar varias devoluciones de llamada en EJB.
Paso | Descripción |
---|---|
1 | Cree un proyecto con un nombre EjbComponent en un paquete com.tutorialspoint.stateless como se explica en el capítulo EJB - Crear aplicación . También puede utilizar el proyecto creado en EJB - Capítulo de persistencia como tal para este capítulo para agregar varias devoluciones de llamada a EJB. |
2 | Cree LibrarySessionBean.java y LibrarySessionBeanRemote como se explica en el capítulo EJB - Crear aplicación . Mantenga el resto de los archivos sin cambios. |
3 | Utilice Beans creados en el capítulo EJB - Persistencia . Agregue métodos de devolución de llamada como se muestra a continuación. Mantenga el resto de los archivos sin cambios. |
4 | Cree una clase de Java BookCallbackListener en el paquete com.tutorialspoint.callback . Esta clase demostrará la separación de los métodos de devolución de llamada. |
5 | Limpie y compile la aplicación para asegurarse de que la lógica empresarial funcione según los requisitos. |
6 | Finalmente, implemente la aplicación en forma de archivo jar en JBoss Application Server. El servidor de aplicaciones JBoss se iniciará automáticamente si aún no se ha iniciado. |
7 | Ahora cree el cliente EJB, una aplicación basada en consola de la misma manera que se explica en el capítulo EJB - Crear aplicación en el temaCreate Client to access EJB. |
EJBComponent (módulo EJB)
BookCallbackListener.java
package com.tutorialspoint.callback;
import javax.persistence.PrePersist;
import javax.persistence.PostLoad;
import javax.persistence.PostPersist;
import javax.persistence.PostRemove;
import javax.persistence.PostUpdate;
import javax.persistence.PreRemove;
import javax.persistence.PreUpdate;
import com.tutorialspoint.entity.Book;
public class BookCallbackListener {
@PrePersist
public void prePersist(Book book) {
System.out.println("BookCallbackListener.prePersist:"
+ "Book to be created with book id: "+book.getId());
}
@PostPersist
public void postPersist(Object book) {
System.out.println("BookCallbackListener.postPersist::"
+ "Book created with book id: "+((Book)book).getId());
}
@PreRemove
public void preRemove(Book book) {
System.out.println("BookCallbackListener.preRemove:"
+ " About to delete Book: " + book.getId());
}
@PostRemove
public void postRemove(Book book) {
System.out.println("BookCallbackListener.postRemove::"
+ " Deleted Book: " + book.getId());
}
@PreUpdate
public void preUpdate(Book book) {
System.out.println("BookCallbackListener.preUpdate::"
+ " About to update Book: " + book.getId());
}
@PostUpdate
public void postUpdate(Book book) {
System.out.println("BookCallbackListener.postUpdate::"
+ " Updated Book: " + book.getId());
}
@PostLoad
public void postLoad(Book book) {
System.out.println("BookCallbackListener.postLoad::"
+ " Loaded Book: " + book.getId());
}
}
Book.java
package com.tutorialspoint.entity;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="books")
public class Book implements Serializable{
private int id;
private String name;
public Book() {
}
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
@Column(name="id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
LibraryStatefulSessionBean.java
package com.tutorialspoint.stateful;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.PostActivate;
import javax.ejb.PrePassivate;
import javax.ejb.Stateful;
@Stateful
public class LibraryStatefulSessionBean
implements LibraryStatefulSessionBeanRemote {
List<String> bookShelf;
public LibraryStatefulSessionBean() {
bookShelf = new ArrayList<String>();
}
public void addBook(String bookName) {
bookShelf.add(bookName);
}
public List<String> getBooks() {
return bookShelf;
}
@PostConstruct
public void postConstruct() {
System.out.println("LibraryStatefulSessionBean.postConstruct::"
+ " bean created.");
}
@PreDestroy
public void preDestroy() {
System.out.println("LibraryStatefulSessionBean.preDestroy:"
+ " bean removed.");
}
@PostActivate
public void postActivate() {
System.out.println("LibraryStatefulSessionBean.postActivate:"
+ " bean activated.");
}
@PrePassivate
public void prePassivate() {
System.out.println("LibraryStatefulSessionBean.prePassivate:"
+ " bean passivated.");
}
}
LibraryStatefulSessionBeanRemote.java
package com.tutorialspoint.stateful;
import java.util.List;
import javax.ejb.Remote;
@Remote
public interface LibraryStatefulSessionBeanRemote {
void addBook(String bookName);
List getBooks();
}
LibraryPersistentBean.java
package com.tutorialspoint.stateless;
import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@Stateless
public class LibraryPersistentBean
implements LibraryPersistentBeanRemote {
public LibraryPersistentBean() {}
@PersistenceContext(unitName="EntityEjbPU")
private EntityManager entityManager;
public void addBook(Book book) {
entityManager.persist(book);
}
public List<Book> getBooks() {
return entityManager.createQuery("From Book")
.getResultList();
}
@PostConstruct
public void postConstruct() {
System.out.println("postConstruct:: LibraryPersistentBean session bean"
+ " created with entity Manager object: ");
}
@PreDestroy
public void preDestroy() {
System.out.println("preDestroy: LibraryPersistentBean session"
+ " bean is removed ");
}
}
LibraryPersistentBeanRemote.java
package com.tutorialspoint.stateless;
import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Remote;
@Remote
public interface LibraryPersistentBeanRemote {
void addBook(Book bookName);
List<Book> getBooks();
}
Tan pronto como implemente el proyecto EjbComponent en JBOSS, observe el registro de jboss.
JBoss ha creado automáticamente una entrada JNDI para nuestro bean de sesión - LibraryPersistentBean/remote.
Usaremos esta cadena de búsqueda para obtener un objeto comercial remoto de tipo: com.tutorialspoint.stateless.LibraryPersistentBeanRemote
Salida de registro del servidor de aplicaciones JBoss
...
16:30:01,401 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
LibraryPersistentBean/remote-com.tutorialspoint.stateless.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryPersistentBean,service=EJB3
16:30:02,723 INFO [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibrarySessionBeanRemote ejbName: LibraryPersistentBean
...
EJBTester (cliente EJB)
jndi.properties
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
Estas propiedades se utilizan para inicializar el objeto InitialContext del servicio de nombres de Java.
El objeto InitialContext se utilizará para buscar un bean de sesión sin estado.
EJBTester.java
package com.tutorialspoint.test;
import com.tutorialspoint.stateful.LibrarySessionBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class EJBTester {
BufferedReader brConsoleReader = null;
Properties props;
InitialContext ctx;
{
props = new Properties();
try {
props.load(new FileInputStream("jndi.properties"));
} catch (IOException ex) {
ex.printStackTrace();
}
try {
ctx = new InitialContext(props);
} catch (NamingException ex) {
ex.printStackTrace();
}
brConsoleReader =
new BufferedReader(new InputStreamReader(System.in));
}
public static void main(String[] args) {
EJBTester ejbTester = new EJBTester();
ejbTester.testEntityEjb();
}
private void showGUI() {
System.out.println("**********************");
System.out.println("Welcome to Book Store");
System.out.println("**********************");
System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
}
private void testEntityEjb() {
try {
int choice = 1;
LibraryPersistentBeanRemote libraryBean =
(LibraryPersistentBeanRemote)
ctx.lookup("LibraryPersistentBean/remote");
while (choice != 2) {
String bookName;
showGUI();
String strChoice = brConsoleReader.readLine();
choice = Integer.parseInt(strChoice);
if (choice == 1) {
System.out.print("Enter book name: ");
bookName = brConsoleReader.readLine();
Book book = new Book();
book.setName(bookName);
libraryBean.addBook(book);
} else if (choice == 2) {
break;
}
}
List<Book> booksList = libraryBean.getBooks();
System.out.println("Book(s) entered so far: " + booksList.size());
int i = 0;
for (Book book:booksList) {
System.out.println((i+1)+". " + book.getName());
i++;
}
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}finally {
try {
if(brConsoleReader !=null) {
brConsoleReader.close();
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}
}
EJBTester realiza las siguientes tareas:
Cargue las propiedades de jndi.properties e inicialice el objeto InitialContext.
En el método testStatelessEjb (), la búsqueda de jndi se realiza con el nombre - "LibrarySessionBean / remote" para obtener el objeto de negocio remoto (EJB sin estado).
Luego, se muestra al usuario una interfaz de usuario de la tienda de la biblioteca y se le solicita que ingrese una opción.
Si el usuario ingresa 1, el sistema solicita el nombre del libro y guarda el libro usando el método addBook () del bean de sesión sin estado. Session Bean está almacenando el libro en la base de datos.
Si el usuario ingresa 2, el sistema recupera libros usando el método getBooks () de bean de sesión sin estado y sale.
Ejecute el cliente para acceder a EJB
Busque EJBTester.java en el explorador de proyectos. Haga clic derecho en la clase EJBTester y seleccionerun file.
Verifique la siguiente salida en la consola de Netbeans.
run:
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 1
Enter book name: Learn Java
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 2
Book(s) entered so far: 1
1. Learn Java
BUILD SUCCESSFUL (total time: 13 seconds)
Salida de registro del servidor de aplicaciones JBoss
Puede encontrar las siguientes entradas de devolución de llamada en el registro de JBoss
14:08:34,293 INFO [STDOUT] postConstruct:: LibraryPersistentBean session bean created with entity Manager object
...
16:39:09,484 INFO [STDOUT] BookCallbackListener.prePersist:: Book to be created with book id: 0
16:39:09,531 INFO [STDOUT] BookCallbackListener.postPersist:: Book created with book id: 1
16:39:09,900 INFO [STDOUT] BookCallbackListener.postLoad:: Loaded Book: 1
...
El servicio de temporizador es un mecanismo mediante el cual se puede construir una aplicación programada. Por ejemplo, generación de nóminas el día 1 de cada mes. La especificación EJB 3.0 ha especificado la anotación @Timeout, que ayuda a programar el servicio EJB en un bean sin estado o controlado por mensajes. EJB Container llama al método, que está anotado por @Timeout.
El servicio de temporizador EJB es un servicio proporcionado por el contenedor EJB, que ayuda a crear un temporizador y programar la devolución de llamada cuando expira el temporizador.
Pasos para crear un temporizador
Inyecte SessionContext en bean usando la anotación @Resource -
@Stateless
public class TimerSessionBean {
@Resource
private SessionContext context;
...
}
Utilice el objeto SessionContext para obtener TimerService y crear un temporizador. Pasa el tiempo en milisegundos y mensaje.
public void createTimer(long duration) {
context.getTimerService().createTimer(duration, "Hello World!");
}
Pasos para usar el temporizador
Use la anotación @Timeout para un método. El tipo de retorno debe ser nulo y pasar un parámetro de tipo Timer. Estamos cancelando el temporizador después de la primera ejecución; de lo contrario, seguirá funcionando después de los intervalos fijos.
@Timeout
public void timeOutHandler(Timer timer) {
System.out.println("timeoutHandler : " + timer.getInfo());
timer.cancel();
}
Aplicación de ejemplo
Creemos una aplicación EJB de prueba para probar Timer Service en EJB.
Paso | Descripción |
---|---|
1 | Cree un proyecto con un nombre EjbComponent en un paquete com.tutorialspoint.timer como se explica en el capítulo EJB - Crear aplicación . |
2 | Cree TimerSessionBean.java y TimerSessionBeanRemote como se explica en el capítulo EJB - Crear aplicación . Mantenga el resto de los archivos sin cambios. |
3 | Limpie y compile la aplicación para asegurarse de que la lógica empresarial funcione según los requisitos. |
4 | Finalmente, implemente la aplicación en forma de archivo jar en JBoss Application Server. El servidor de aplicaciones JBoss se iniciará automáticamente si aún no se ha iniciado. |
5 | Ahora cree el cliente EJB, una aplicación basada en consola de la misma manera que se explica en el capítulo EJB - Crear aplicación en el temaCreate Client to access EJB. |
EJBComponent (módulo EJB)
TimerSessionBean.java
package com.tutorialspoint.timer;
import javax.annotation.Resource;
import javax.ejb.SessionContext;
import javax.ejb.Timer;
import javax.ejb.Stateless;
import javax.ejb.Timeout;
@Stateless
public class TimerSessionBean implements TimerSessionBeanRemote {
@Resource
private SessionContext context;
public void createTimer(long duration) {
context.getTimerService().createTimer(duration, "Hello World!");
}
@Timeout
public void timeOutHandler(Timer timer) {
System.out.println("timeoutHandler : " + timer.getInfo());
timer.cancel();
}
}
TimerSessionBeanRemote.java
package com.tutorialspoint.timer;
import javax.ejb.Remote;
@Remote
public interface TimerSessionBeanRemote {
public void createTimer(long milliseconds);
}
Tan pronto como implemente el proyecto EjbComponent en JBOSS, observe el registro de jboss.
JBoss ha creado automáticamente una entrada JNDI para nuestro bean de sesión - TimerSessionBean/remote.
Usaremos esta cadena de búsqueda para obtener un objeto comercial remoto de tipo: com.tutorialspoint.timer.TimerSessionBeanRemote
Salida de registro del servidor de aplicaciones JBoss
...
16:30:01,401 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
TimerSessionBean/remote - EJB3.x Default Remote Business Interface
TimerSessionBean/remote-com.tutorialspoint.timer.TimerSessionBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=TimerSessionBean,service=EJB3
16:30:02,723 INFO [EJBContainer] STARTED EJB: com.tutorialspoint.timer.TimerSessionBeanRemote ejbName: TimerSessionBean
...
EJBTester (cliente EJB)
jndi.properties
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
Estas propiedades se utilizan para inicializar el objeto InitialContext del servicio de nombres de Java.
El objeto InitialContext se utilizará para buscar un bean de sesión sin estado.
EJBTester.java
package com.tutorialspoint.test;
import com.tutorialspoint.stateful.TimerSessionBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class EJBTester {
BufferedReader brConsoleReader = null;
Properties props;
InitialContext ctx;
{
props = new Properties();
try {
props.load(new FileInputStream("jndi.properties"));
} catch (IOException ex) {
ex.printStackTrace();
}
try {
ctx = new InitialContext(props);
} catch (NamingException ex) {
ex.printStackTrace();
}
brConsoleReader =
new BufferedReader(new InputStreamReader(System.in));
}
public static void main(String[] args) {
EJBTester ejbTester = new EJBTester();
ejbTester.testTimerService();
}
private void showGUI() {
System.out.println("**********************");
System.out.println("Welcome to Book Store");
System.out.println("**********************");
System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
}
private void testTimerService() {
try {
TimerSessionBeanRemote timerServiceBean = (TimerSessionBeanRemote)ctx.lookup("TimerSessionBean/remote");
System.out.println("["+(new Date()).toString()+ "]" + "timer created.");
timerServiceBean.createTimer(2000);
} catch (NamingException ex) {
ex.printStackTrace();
}
}
}
EJBTester está realizando las siguientes tareas.
Cargue las propiedades de jndi.properties e inicialice el objeto InitialContext.
En el método testTimerService (), la búsqueda de jndi se realiza con el nombre "TimerSessionBean / remote" para obtener el objeto de negocio remoto (temporizador EJB sin estado).
Luego se invoca createTimer pasando 2000 milisegundos como tiempo de programación.
EJB Container llama al método timeoutHandler después de 2 segundos.
Ejecute el cliente para acceder a EJB
Busque EJBTester.java en el explorador de proyectos. Haga clic derecho en la clase EJBTester y seleccionerun file.
Verifique la siguiente salida en la consola de Netbeans.
run:
[Wed Jun 19 11:35:47 IST 2013]timer created.
BUILD SUCCESSFUL (total time: 0 seconds)
Salida de registro del servidor de aplicaciones JBoss
Puede encontrar las siguientes entradas de devolución de llamada en el registro de JBoss
...
11:35:49,555 INFO [STDOUT] timeoutHandler : Hello World!
...
La especificación EJB 3.0 proporciona anotaciones, que se pueden aplicar en campos o métodos de establecimiento para inyectar dependencias. EJB Container utiliza el registro JNDI global para localizar la dependencia. Las siguientes anotaciones se utilizan en EJB 3.0 para la inyección de dependencia.
@EJB - utilizado para inyectar otra referencia EJB.
@Resource - utilizado para inyectar servicios de fuente de datos o singleton como sessionContext, timerService, etc.
Pasos para usar @EJB
@EJB se puede utilizar en campos o métodos de la siguiente manera:
public class LibraryMessageBean implements MessageListener {
//dependency injection on field.
@EJB
LibraryPersistentBeanRemote libraryBean;
...
}
public class LibraryMessageBean implements MessageListener {
LibraryPersistentBeanRemote libraryBean;
//dependency injection on method.
@EJB(beanName="com.tutorialspoint.stateless.LibraryPersistentBean")
public void setLibraryPersistentBean(
LibraryPersistentBeanRemote libraryBean)
{
this.libraryBean = libraryBean;
}
...
}
Pasos para usar @Resource
@Resource se usa normalmente para inyectar singletons proporcionados por el contenedor EJB.
public class LibraryMessageBean implements MessageListener {
@Resource
private MessageDrivenContext mdctx;
...
}
Aplicación de ejemplo
Creemos una aplicación EJB de prueba para probar el servicio de inyección de dependencia en EJB.
Paso | Descripción |
---|---|
1 | Cree un proyecto con un nombre EjbComponent en un paquete com.tutorialspoint.timer como se explica en el capítulo EJB - Crear aplicación . |
2 | Utilice Beans creados en el capítulo EJB - Bean controlado por mensajes . Mantenga el resto de los archivos sin cambios. |
3 | Limpie y compile la aplicación para asegurarse de que la lógica empresarial funcione según los requisitos. |
4 | Finalmente, implemente la aplicación en forma de archivo jar en JBoss Application Server. El servidor de aplicaciones JBoss se iniciará automáticamente si aún no se ha iniciado. |
5 | Ahora cree el cliente EJB, una aplicación basada en consola de la misma manera que se explica en el capítulo EJB - Crear aplicación en el temaCreate Client to access EJB. |
EJBComponent (módulo EJB)
LibraryMessageBean.java
package com.tuturialspoint.messagebean;
import com.tutorialspoint.entity.Book;
import com.tutorialspoint.stateless.LibraryPersistentBeanRemote;
import javax.annotation.Resource;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.EJB;
import javax.ejb.MessageDriven;
import javax.ejb.MessageDrivenContext;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
@MessageDriven(
name = "BookMessageHandler",
activationConfig = {
@ActivationConfigProperty( propertyName = "destinationType",
propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty( propertyName = "destination",
propertyValue ="/queue/BookQueue")
}
)
public class LibraryMessageBean implements MessageListener {
@Resource
private MessageDrivenContext mdctx;
@EJB
LibraryPersistentBeanRemote libraryBean;
public LibraryMessageBean() {
}
public void onMessage(Message message) {
ObjectMessage objectMessage = null;
try {
objectMessage = (ObjectMessage) message;
Book book = (Book) objectMessage.getObject();
libraryBean.addBook(book);
}catch (JMSException ex) {
mdctx.setRollbackOnly();
}
}
}
EJBTester (cliente EJB)
EJBTester.java
package com.tutorialspoint.test;
import com.tutorialspoint.entity.Book;
import com.tutorialspoint.stateless.LibraryPersistentBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class EJBTester {
BufferedReader brConsoleReader = null;
Properties props;
InitialContext ctx;
{
props = new Properties();
try {
props.load(new FileInputStream("jndi.properties"));
} catch (IOException ex) {
ex.printStackTrace();
}
try {
ctx = new InitialContext(props);
} catch (NamingException ex) {
ex.printStackTrace();
}
brConsoleReader =
new BufferedReader(new InputStreamReader(System.in));
}
public static void main(String[] args) {
EJBTester ejbTester = new EJBTester();
ejbTester.testMessageBeanEjb();
}
private void showGUI() {
System.out.println("**********************");
System.out.println("Welcome to Book Store");
System.out.println("**********************");
System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
}
private void testMessageBeanEjb() {
try {
int choice = 1;
Queue queue = (Queue) ctx.lookup("/queue/BookQueue");
QueueConnectionFactory factory =
(QueueConnectionFactory) ctx.lookup("ConnectionFactory");
QueueConnection connection = factory.createQueueConnection();
QueueSession session = connection.createQueueSession(
false, QueueSession.AUTO_ACKNOWLEDGE);
QueueSender sender = session.createSender(queue);
while (choice != 2) {
String bookName;
showGUI();
String strChoice = brConsoleReader.readLine();
choice = Integer.parseInt(strChoice);
if (choice == 1) {
System.out.print("Enter book name: ");
bookName = brConsoleReader.readLine();
Book book = new Book();
book.setName(bookName);
ObjectMessage objectMessage =
session.createObjectMessage(book);
sender.send(objectMessage);
} else if (choice == 2) {
break;
}
}
LibraryPersistentBeanRemote libraryBean =
(LibraryPersistentBeanRemote)
ctx.lookup("LibraryPersistentBean/remote");
List<Book> booksList = libraryBean.getBooks();
System.out.println("Book(s) entered so far: "
+ booksList.size());
int i = 0;
for (Book book:booksList) {
System.out.println((i+1)+". " + book.getName());
i++;
}
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}finally {
try {
if(brConsoleReader !=null) {
brConsoleReader.close();
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}
}
EJBTester realiza las siguientes tareas:
Cargue las propiedades de jndi.properties e inicialice el objeto InitialContext.
En el método testStatefulEjb (), la búsqueda de jndi se realiza con el nombre - "/ queue / BookQueue" para obtener la referencia de la cola disponible en Jboss. Luego, el remitente se crea usando la sesión de cola.
Luego, se muestra al usuario una interfaz de usuario de la tienda de la biblioteca y se le pide que ingrese una opción.
Si el usuario ingresa 1, el sistema solicita el nombre del libro y el remitente envía el nombre del libro a la cola. Cuando el contenedor JBoss recibe este mensaje en la cola, llama al método onMessage de nuestro bean controlado por mensajes. Nuestro bean controlado por mensajes luego guarda el libro usando el método addBook () del bean de sesión con estado. Session Bean mantiene el libro en la base de datos a través de la llamada EntityManager.
Si el usuario ingresa 2, entonces se realiza otra búsqueda jndi con el nombre - "LibraryStatefulSessionBean / remote" para obtener el objeto comercial remoto (EJB con estado) nuevamente y se realiza la lista de libros.
Ejecute el cliente para acceder a EJB
Busque EJBTester.java en el explorador de proyectos. Haga clic derecho en la clase EJBTester y seleccionerun file.
Verifique la siguiente salida en la consola de Netbeans.
run:
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 1
Enter book name: Learn EJB
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 2
Book(s) entered so far: 2
1. learn java
1. learn EJB
BUILD SUCCESSFUL (total time: 15 seconds)
La salida que se muestra arriba indica que nuestro bean controlado por mensajes está recibiendo el mensaje y almacenando el libro en almacenamiento persistente y los libros se recuperan de la base de datos.
Nuestro bean controlado por mensajes está usando LibraryPersistentBean inyectado en él usando la anotación @EJB y, en caso de excepción, MessageDrivenContext, el objeto se usa para revertir la transacción.
EJB 3.0 proporciona especificaciones para interceptar llamadas a métodos comerciales utilizando métodos anotados con la anotación @AroundInvoke. EjbContainer llama a un método interceptor antes de que la llamada al método empresarial lo intercepte. A continuación se muestra la firma de ejemplo de un método interceptor
@AroundInvoke
public Object methodInterceptor(InvocationContext ctx) throws Exception {
System.out.println("*** Intercepting call to LibraryBean method: "
+ ctx.getMethod().getName());
return ctx.proceed();
}
Los métodos de interceptor se pueden aplicar o limitar en tres niveles.
Default - El interceptor predeterminado se invoca para cada bean dentro de la implementación. El interceptor predeterminado se puede aplicar solo a través de xml (ejb-jar.xml).
Class- El interceptor de nivel de clase se invoca para cada método del bean. El interceptor de nivel de clase se puede aplicar tanto mediante una anotación como a través de xml (ejb-jar.xml).
Method- El interceptor de nivel de método se invoca para un método particular del bean. El interceptor de nivel de método se puede aplicar tanto mediante una anotación como a través de xml (ejb-jar.xml).
Estamos discutiendo el interceptor de nivel de clase aquí.
Clase de interceptor
package com.tutorialspoint.interceptor;
import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;
public class BusinessInterceptor {
@AroundInvoke
public Object methodInterceptor(InvocationContext ctx) throws Exception {
System.out.println("*** Intercepting call to LibraryBean method: "
+ ctx.getMethod().getName());
return ctx.proceed();
}
}
Interfaz remota
import javax.ejb.Remote;
@Remote
public interface LibraryBeanRemote {
//add business method declarations
}
EJB sin estado interceptado
@Interceptors ({BusinessInterceptor.class})
@Stateless
public class LibraryBean implements LibraryBeanRemote {
//implement business method
}
Aplicación de ejemplo
Creemos una aplicación EJB de prueba para probar EJB sin estado interceptado.
Paso | Descripción |
---|---|
1 | Cree un proyecto con un nombre EjbComponent bajo un paquete com.tutorialspoint.interceptor como se explica en el capítulo EJB - Crear aplicación . También puede utilizar el proyecto creado en el capítulo EJB - Crear aplicación como tal para que este capítulo comprenda los conceptos de EJB interceptados. |
2 | Cree LibraryBean.java y LibraryBeanRemote en el paquete com.tutorialspoint.interceptor como se explica en el capítulo EJB - Crear aplicación . Mantenga el resto de los archivos sin cambios. |
3 | Limpie y compile la aplicación para asegurarse de que la lógica empresarial funcione según los requisitos. |
4 | Finalmente, implemente la aplicación en forma de archivo jar en JBoss Application Server. El servidor de aplicaciones JBoss se iniciará automáticamente si aún no se ha iniciado. |
5 | Ahora cree el cliente ejb, una aplicación basada en consola de la misma manera que se explica en el capítulo EJB - Crear aplicación en el temaCreate Client to access EJB. |
EJBComponent (módulo EJB)
LibraryBeanRemote.java
package com.tutorialspoint.interceptor;
import java.util.List;
import javax.ejb.Remote;
@Remote
public interface LibraryBeanRemote {
void addBook(String bookName);
List getBooks();
}
LibraryBean.java
package com.tutorialspoint.interceptor;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;
import javax.interceptor.Interceptors;
@Interceptors ({BusinessInterceptor.class})
@Stateless
public class LibraryBean implements LibraryBeanRemote {
List<String> bookShelf;
public LibraryBean() {
bookShelf = new ArrayList<String>();
}
public void addBook(String bookName) {
bookShelf.add(bookName);
}
public List<String> getBooks() {
return bookShelf;
}
}
Tan pronto como implemente el proyecto EjbComponent en JBOSS, observe el registro de jboss.
JBoss ha creado automáticamente una entrada JNDI para nuestro bean de sesión - LibraryBean/remote.
Usaremos esta cadena de búsqueda para obtener un objeto comercial remoto de tipo: com.tutorialspoint.interceptor.LibraryBeanRemote
Salida de registro del servidor de aplicaciones JBoss
...
16:30:01,401 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
LibraryBean/remote - EJB3.x Default Remote Business Interface
LibraryBean/remote-com.tutorialspoint.interceptor.LibraryBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryBean,service=EJB3
16:30:02,723 INFO [EJBContainer] STARTED EJB: com.tutorialspoint.interceptor.LibraryBeanRemote ejbName: LibraryBean
16:30:02,731 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
LibraryBean/remote - EJB3.x Default Remote Business Interface
LibraryBean/remote-com.tutorialspoint.interceptor.LibraryBeanRemote - EJB3.x Remote Business Interface
...
EJBTester (cliente EJB)
jndi.properties
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
Estas propiedades se utilizan para inicializar el objeto InitialContext del servicio de nombres de Java.
El objeto InitialContext se utilizará para buscar un bean de sesión sin estado.
EJBTester.java
package com.tutorialspoint.test;
import com.tutorialspoint.stateful.LibraryBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class EJBTester {
BufferedReader brConsoleReader = null;
Properties props;
InitialContext ctx;
{
props = new Properties();
try {
props.load(new FileInputStream("jndi.properties"));
} catch (IOException ex) {
ex.printStackTrace();
}
try {
ctx = new InitialContext(props);
} catch (NamingException ex) {
ex.printStackTrace();
}
brConsoleReader =
new BufferedReader(new InputStreamReader(System.in));
}
public static void main(String[] args) {
EJBTester ejbTester = new EJBTester();
ejbTester.testInterceptedEjb();
}
private void showGUI() {
System.out.println("**********************");
System.out.println("Welcome to Book Store");
System.out.println("**********************");
System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
}
private void testInterceptedEjb() {
try {
int choice = 1;
LibraryBeanRemote libraryBean =
LibraryBeanRemote)ctx.lookup("LibraryBean/remote");
while (choice != 2) {
String bookName;
showGUI();
String strChoice = brConsoleReader.readLine();
choice = Integer.parseInt(strChoice);
if (choice == 1) {
System.out.print("Enter book name: ");
bookName = brConsoleReader.readLine();
Book book = new Book();
book.setName(bookName);
libraryBean.addBook(book);
} else if (choice == 2) {
break;
}
}
List<Book> booksList = libraryBean.getBooks();
System.out.println("Book(s) entered so far: " + booksList.size());
int i = 0;
for (Book book:booksList) {
System.out.println((i+1)+". " + book.getName());
i++;
}
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}finally {
try {
if(brConsoleReader !=null) {
brConsoleReader.close();
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}
}
EJBTester realiza las siguientes tareas:
Cargue las propiedades de jndi.properties e inicialice el objeto InitialContext.
En el método testInterceptedEjb (), la búsqueda de jndi se realiza con el nombre - "LibraryBean / remote" para obtener el objeto comercial remoto (EJB sin estado).
Luego, se muestra al usuario una interfaz de usuario de la tienda de la biblioteca y se le solicita que ingrese una opción.
Si el usuario ingresa 1, el sistema solicita el nombre del libro y guarda el libro usando el método addBook () del bean de sesión sin estado. Session Bean está almacenando el libro en su variable de instancia.
Si el usuario ingresa 2, el sistema recupera libros usando el método getBooks () del bean de sesión sin estado y sale.
Ejecute el cliente para acceder a EJB
Busque EJBTester.java en el explorador de proyectos. Haga clic derecho en la clase EJBTester y seleccionerun file.
Verifique la siguiente salida en la consola de Netbeans.
run:
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 1
Enter book name: Learn Java
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 2
Book(s) entered so far: 1
1. Learn Java
BUILD SUCCESSFUL (total time: 13 seconds)
Salida de registro del servidor de aplicaciones JBoss
Verifique la siguiente salida en la salida de registro del servidor de aplicaciones JBoss.
....
09:55:40,741 INFO [STDOUT] *** Intercepting call to LibraryBean method: addBook
09:55:43,661 INFO [STDOUT] *** Intercepting call to LibraryBean method: getBooks
EJB 3.0 ofrece la opción de incrustar JAVA POJO (Plain Old Java Object) en un bean de entidad y permite mapear nombres de columna con los métodos de la clase POJO incrustada. Un POJO de Java que se incrustará debe anotarse como @Embeddable.
@Embeddable
public class Publisher implements Serializable{
private String name;
private String address;
...
}
La clase anterior se puede incrustar utilizando la anotación @Embedded.
@Entity
public class Book implements Serializable{
private int id;
private String name;
private Publisher publisher;
...
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "name",
column = @Column(name = "PUBLISHER")),
@AttributeOverride(name = "address",
column = @Column(name = "PUBLISHER_ADDRESS"))
})
public Publisher getPublisher() {
return publisher;
}
...
}
Aplicación de ejemplo
Creemos una aplicación EJB de prueba para probar objetos incrustados en EJB 3.0.
Paso | Descripción |
---|---|
1 | Cree un proyecto con un nombre EjbComponent en un paquete com.tutorialspoint.entity como se explica en el capítulo EJB - Crear aplicación . Utilice el proyecto creado en el capítulo EJB - Persistencia como tal para este capítulo para comprender los objetos incrustados en los conceptos de EJB. |
2 | Cree Publisher.java en el paquete com.tutorialspoint.entity como se explica en el capítulo EJB - Crear aplicación . Mantenga el resto de los archivos sin cambios. |
3 | Cree Book.java en el paquete com.tutorialspoint.entity . Utilice el capítulo EJB - Persistencia como referencia. Mantenga el resto de los archivos sin cambios. |
4 | Limpie y compile la aplicación para asegurarse de que la lógica empresarial funcione según los requisitos. |
5 | Finalmente, implemente la aplicación en forma de archivo jar en JBoss Application Server. El servidor de aplicaciones JBoss se iniciará automáticamente si aún no se ha iniciado. |
6 | Ahora cree el cliente EJB, una aplicación basada en consola de la misma manera que se explica en el capítulo EJB - Crear aplicación en el temaCreate Client to access EJB. |
Crear / modificar tabla de libro
CREATE TABLE book (
id integer PRIMARY KEY,
name varchar(50)
);
Alter table book add publisher varchar(100);
Alter table book add publisher_address varchar(200);
EJBComponent (módulo EJB)
Publisher.java
package com.tutorialspoint.entity;
import java.io.Serializable;
import javax.persistence.Embeddable;
@Embeddable
public class Publisher implements Serializable{
private String name;
private String address;
public Publisher() {}
public Publisher(String name, String address) {
this.name = name;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String toString() {
return name + "," + address;
}
}
Book.java
package com.tutorialspoint.entity;
import com.tutorialspoint.callback.BookCallbackListener;
import java.io.Serializable;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="book")
public class Book implements Serializable{
private int id;
private String name;
private Publisher publisher;
public Book() {
}
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
@Column(name="id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "name",
column = @Column(name = "PUBLISHER")),
@AttributeOverride(name = "address",
column = @Column(name = "PUBLISHER_ADDRESS"))
})
public Publisher getPublisher() {
return publisher;
}
public void setPublisher(Publisher publisher) {
this.publisher = publisher;
}
}
LibraryPersistentBeanRemote.java
package com.tutorialspoint.stateless;
import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Remote;
@Remote
public interface LibraryPersistentBeanRemote {
void addBook(Book bookName);
List<Book> getBooks();
}
LibraryPersistentBean.java
package com.tutorialspoint.stateless;
import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
public LibraryPersistentBean() {
}
@PersistenceContext(unitName="EjbComponentPU")
private EntityManager entityManager;
public void addBook(Book book) {
entityManager.persist(book);
}
public List<Book> getBooks() {
return entityManager.createQuery("From Book").getResultList();
}
}
Tan pronto como implemente el proyecto EjbComponent en JBOSS, observe el registro de jboss.
JBoss ha creado automáticamente una entrada JNDI para nuestro bean de sesión - LibraryPersistentBean/remote.
Usaremos esta cadena de búsqueda para obtener un objeto comercial remoto de tipo: com.tutorialspoint.interceptor.LibraryPersistentBeanRemote
Salida de registro del servidor de aplicaciones JBoss
...
16:30:01,401 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
LibraryPersistentBean/remote-com.tutorialspoint.interceptor.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryPersistentBean,service=EJB3
16:30:02,723 INFO [EJBContainer] STARTED EJB: com.tutorialspoint.interceptor.LibraryPersistentBeanRemote ejbName: LibraryPersistentBean
16:30:02,731 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
LibraryPersistentBean/remote-com.tutorialspoint.interceptor.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
...
EJBTester (cliente EJB)
jndi.properties
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
Estas propiedades se utilizan para inicializar el objeto InitialContext del servicio de nombres de Java.
El objeto InitialContext se utilizará para buscar un bean de sesión sin estado.
EJBTester.java
package com.tutorialspoint.test;
import com.tutorialspoint.stateful.LibraryBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class EJBTester {
BufferedReader brConsoleReader = null;
Properties props;
InitialContext ctx;
{
props = new Properties();
try {
props.load(new FileInputStream("jndi.properties"));
} catch (IOException ex) {
ex.printStackTrace();
}
try {
ctx = new InitialContext(props);
} catch (NamingException ex) {
ex.printStackTrace();
}
brConsoleReader =
new BufferedReader(new InputStreamReader(System.in));
}
public static void main(String[] args) {
EJBTester ejbTester = new EJBTester();
ejbTester.testEmbeddedObjects();
}
private void showGUI() {
System.out.println("**********************");
System.out.println("Welcome to Book Store");
System.out.println("**********************");
System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
}
private void testEmbeddedObjects() {
try {
int choice = 1;
LibraryPersistentBeanRemote libraryBean =
(LibraryPersistentBeanRemote)
ctx.lookup("LibraryPersistentBean/remote");
while (choice != 2) {
String bookName;
String publisherName;
String publisherAddress;
showGUI();
String strChoice = brConsoleReader.readLine();
choice = Integer.parseInt(strChoice);
if (choice == 1) {
System.out.print("Enter book name: ");
bookName = brConsoleReader.readLine();
System.out.print("Enter publisher name: ");
publisherName = brConsoleReader.readLine();
System.out.print("Enter publisher address: ");
publisherAddress = brConsoleReader.readLine();
Book book = new Book();
book.setName(bookName);
book.setPublisher
(new Publisher(publisherName,publisherAddress));
libraryBean.addBook(book);
} else if (choice == 2) {
break;
}
}
List<Book> booksList = libraryBean.getBooks();
System.out.println("Book(s) entered so far: " + booksList.size());
int i = 0;
for (Book book:booksList) {
System.out.println((i+1)+". " + book.getName());
System.out.println("Publication: "+book.getPublisher());
i++;
}
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}finally {
try {
if(brConsoleReader !=null) {
brConsoleReader.close();
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}
}
EJBTester realiza las siguientes tareas:
Cargue las propiedades de jndi.properties e inicialice el objeto InitialContext.
En el método testInterceptedEjb (), la búsqueda de jndi se realiza con el nombre "LibraryPersistenceBean / remote" para obtener el objeto de negocio remoto (EJB sin estado).
Luego, se muestra al usuario una interfaz de usuario de la tienda de la biblioteca y se le pide que ingrese una opción.
Si el usuario ingresa 1, el sistema solicita el nombre del libro y guarda el libro usando el método addBook () del bean de sesión sin estado. Session Bean está almacenando el libro en la base de datos.
Si el usuario ingresa 2, el sistema recupera libros usando el método getBooks () del bean de sesión sin estado y sale.
Ejecute el cliente para acceder a EJB
Busque EJBTester.java en el explorador de proyectos. Haga clic derecho en la clase EJBTester y seleccionerun file.
Verifique la siguiente salida en la consola de Netbeans.
run:
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 1
Enter book name: learn html5
Enter publisher name: SAMS
Enter publisher address: DELHI
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 2
Book(s) entered so far: 1
1. learn html5
Publication: SAMS,DELHI
BUILD SUCCESSFUL (total time: 21 seconds)
EJB 3.0 proporciona compatibilidad con los tipos Blob y Clob mediante la anotación @Lob. Los siguientes tipos de Java se pueden asignar mediante la anotación @Lob.
- java.sql.Blob
- java.sql.Clob
- byte[]
- String
- Objeto serializable
@Entity
@Table(name="books")
@EntityListeners(BookCallbackListener.class)
public class Book implements Serializable{
...
private byte[] image;
@Lob @Basic(fetch= FetchType.EAGER)
public byte[] getImage() {
return image;
}
...
}
Aplicación de ejemplo
Creemos una aplicación EJB de prueba para probar la compatibilidad con blob / clob en EJB 3.0.
Paso | Descripción |
---|---|
1 | Cree un proyecto con un nombre EjbComponent en un paquete com.tutorialspoint.entity como se explica en el capítulo EJB - Crear aplicación . Utilice el proyecto creado en el capítulo EJB - Persistencia como tal para este capítulo para comprender los objetos clob / blob en los conceptos ejb. |
2 | Cree Book.java en el paquete com.tutorialspoint.entity . Utilice el capítulo EJB - Persistencia como referencia. Mantenga el resto de los archivos sin cambios. |
3 | Limpie y compile la aplicación para asegurarse de que la lógica empresarial funcione según los requisitos. |
4 | Finalmente, implemente la aplicación en forma de archivo jar en JBoss Application Server. El servidor de aplicaciones JBoss se iniciará automáticamente si aún no se ha iniciado. |
5 | Ahora cree el cliente EJB, una aplicación basada en consola de la misma manera que se explica en el capítulo EJB - Crear aplicación en el temaCreate Client to access EJB. |
Crear / modificar tabla de libro
CREATE TABLE book (
id integer PRIMARY KEY,
name varchar(50)
);
Alter table book add image bytea;
Alter table book add xml text;
EJBComponent (módulo EJB)
Book.java
package com.tutorialspoint.entity;
import com.tutorialspoint.callback.BookCallbackListener;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;
@Entity
@Table(name="book")
public class Book implements Serializable{
private int id;
private String name;
private byte[] image;
private String xml;
public Book() {
}
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
@Column(name="id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Lob @Basic(fetch= FetchType.EAGER)
public byte[] getImage() {
return image;
}
public void setImage(byte[] image) {
this.image = image;
}
@Lob @Basic(fetch= FetchType.EAGER)
public String getXml() {
return xml;
}
public void setXml(String xml) {
this.xml = xml;
}
}
LibraryPersistentBeanRemote.java
package com.tutorialspoint.stateless;
import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Remote;
@Remote
public interface LibraryPersistentBeanRemote {
void addBook(Book bookName);
List<Book> getBooks();
}
LibraryPersistentBean.java
package com.tutorialspoint.stateless;
import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
public LibraryPersistentBean() {
}
@PersistenceContext(unitName="EjbComponentPU")
private EntityManager entityManager;
public void addBook(Book book) {
entityManager.persist(book);
}
public List<Book> getBooks() {
return entityManager.createQuery("From Book").getResultList();
}
}
Tan pronto como implemente el proyecto EjbComponent en JBOSS, observe el registro de jboss.
JBoss ha creado automáticamente una entrada JNDI para nuestro bean de sesión - LibraryPersistentBean/remote.
Usaremos esta cadena de búsqueda para obtener un objeto comercial remoto de tipo: com.tutorialspoint.interceptor.LibraryPersistentBeanRemote
Salida de registro del servidor de aplicaciones JBoss
...
16:30:01,401 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
LibraryPersistentBean/remote-com.tutorialspoint.interceptor.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryPersistentBean,service=EJB3
16:30:02,723 INFO [EJBContainer] STARTED EJB: com.tutorialspoint.interceptor.LibraryPersistentBeanRemote ejbName: LibraryPersistentBean
16:30:02,731 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
LibraryPersistentBean/remote-com.tutorialspoint.interceptor.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
...
EJBTester (cliente EJB)
jndi.properties
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
Estas propiedades se utilizan para inicializar el objeto InitialContext del servicio de nombres de Java.
El objeto InitialContext se utilizará para buscar un bean de sesión sin estado.
EJBTester.java
package com.tutorialspoint.test;
import com.tutorialspoint.stateful.LibraryBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class EJBTester {
BufferedReader brConsoleReader = null;
Properties props;
InitialContext ctx;
{
props = new Properties();
try {
props.load(new FileInputStream("jndi.properties"));
} catch (IOException ex) {
ex.printStackTrace();
}
try {
ctx = new InitialContext(props);
} catch (NamingException ex) {
ex.printStackTrace();
}
brConsoleReader =
new BufferedReader(new InputStreamReader(System.in));
}
public static void main(String[] args) {
EJBTester ejbTester = new EJBTester();
ejbTester.testBlobClob();
}
private void showGUI() {
System.out.println("**********************");
System.out.println("Welcome to Book Store");
System.out.println("**********************");
System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
}
private void testBlobClob() {
try {
int choice = 1;
LibraryPersistentBeanRemote libraryBean =
(LibraryPersistentBeanRemote)
ctx.lookup("LibraryPersistentBean/remote");
while (choice != 2) {
String bookName;
String publisherName;
String publisherAddress;
showGUI();
String strChoice = brConsoleReader.readLine();
choice = Integer.parseInt(strChoice);
if (choice == 1) {
System.out.print("Enter book name: ");
bookName = brConsoleReader.readLine();
String xml = "<book><name>"+bookName+"</name></book>";
Book book = new Book();
book.setName(bookName);
byte[] imageBytes = {0x32, 0x32,0x32, 0x32,0x32,
0x32,0x32, 0x32,
0x32, 0x32,0x32, 0x32,0x32, 0x32,0x32, 0x32,
0x32, 0x32,0x32, 0x32,0x32, 0x32,0x32, 0x32
};
book.setImage(imageBytes);
book.setXml(xml);
libraryBean.addBook(book);
} else if (choice == 2) {
break;
}
}
List<Book> booksList = libraryBean.getBooks();
System.out.println("Book(s) entered so far: " + booksList.size());
int i = 0;
for (Book book:booksList) {
System.out.println((i+1)+". " + book.getName());
byte[] imageByts = book.getImage();
if(imageByts != null) {
System.out.print("image bytes: [");
for(int j = 0; j < imageByts.length ; j++) {
System.out.print("0x"
+ String.format("%x", imageByts[j]) +" ");
}
System.out.println("]");
}
System.out.println(book.getXml());
i++;
}
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}finally {
try {
if(brConsoleReader !=null) {
brConsoleReader.close();
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}
}
EJBTester realiza las siguientes tareas.
Cargue las propiedades de jndi.properties e inicialice el objeto InitialContext.
En el método testInterceptedEjb (), la búsqueda de jndi se realiza con el nombre - "LibraryPersistenceBean / remote" para obtener el objeto comercial remoto (EJB sin estado).
Luego, se muestra al usuario una interfaz de usuario de la tienda de la biblioteca y se le pide que ingrese una opción.
Si el usuario ingresa 1, el sistema solicita el nombre del libro y guarda el libro usando el método addBook () del bean de sesión sin estado. Session Bean está almacenando el libro en la base de datos.
Si el usuario ingresa 2, el sistema recupera libros usando el método getBooks () del bean de sesión sin estado y sale.
Ejecute el cliente para acceder a EJB
Busque EJBTester.java en el explorador de proyectos. Haga clic derecho en la clase EJBTester y seleccionerun file.
Verifique la siguiente salida en la consola de Netbeans.
run:
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 1
Enter book name: learn testing
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 2
Book(s) entered so far: 1
1. learn testing
image bytes: [
0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 ]
<book><name>learn testing</name></book>
BUILD SUCCESSFUL (total time: 20 seconds)
Una transacción es una sola unidad de elementos de trabajo, que sigue las propiedades de ACID. ACID significa Atómico, Consistente, Aislado y Durable.
Atomic- Si alguno de los elementos de trabajo falla, toda la unidad se considerará fallada. El éxito significa que todos los elementos se ejecutan correctamente.
Consistent - Una transacción debe mantener el sistema en un estado consistente.
Isolated - Cada transacción se ejecuta independientemente de cualquier otra transacción.
Durable - La transacción debe sobrevivir a la falla del sistema si se ha ejecutado o confirmado.
EJB Container / Servers son servidores de transacciones y manejan la propagación del contexto de las transacciones y las transacciones distribuidas. Las transacciones pueden ser administradas por el contenedor o por manejo de código personalizado en el código de bean.
Container Managed Transactions - En este tipo, el contenedor gestiona los estados de la transacción.
Bean Managed Transactions - En este tipo, el desarrollador gestiona el ciclo de vida de los estados de las transacciones.
Transacciones gestionadas por contenedor
EJB 3.0 ha especificado los siguientes atributos de transacciones, que implementan los contenedores EJB:
REQUIRED - Indica que el método comercial debe ejecutarse dentro de la transacción; de lo contrario, se iniciará una nueva transacción para ese método.
REQUIRES_NEW - Indica que se va a iniciar una nueva transacción para el método comercial.
SUPPORTS - Indica que el método comercial se ejecutará como parte de la transacción.
NOT_SUPPORTED - Indica que el método comercial no debe ejecutarse como parte de la transacción.
MANDATORY - Indica que el método comercial se ejecutará como parte de la transacción; de lo contrario, se lanzará una excepción.
NEVER - Indica si el método comercial se ejecuta como parte de la transacción, entonces se lanzará una excepción.
Ejemplo
package com.tutorialspoint.txn.required;
import javax.ejb.*
@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class UserDetailBean implements UserDetailRemote {
private UserDetail;
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void createUserDetail() {
//create user details object
}
}
El método de negocio createUserDetail () se hace Obligatorio usando la anotación Requerida.
package com.tutorialspoint.txn.required;
import javax.ejb.*
@Stateless
public class UserSessionBean implements UserRemote {
private User;
@EJB
private UserDetailRemote userDetail;
public void createUser() {
//create user
//...
//create user details
userDetail.createUserDetail();
}
}
El método de negocio createUser () está utilizando createUserDetail (). Si se produjo una excepción durante la llamada a createUser () y no se crea el objeto User, tampoco se creará el objeto UserDetail.
Transacciones gestionadas por Bean
En Bean Managed Transactions, las transacciones se pueden administrar manejando excepciones a nivel de aplicación.
Los siguientes son los puntos clave a considerar:
Start - Cuándo iniciar una transacción en un método comercial.
Sucess - Identificar el escenario de éxito cuando se va a realizar una transacción.
Failed - Identificar el escenario de falla cuando una transacción debe revertirse.
Ejemplo
package com.tutorialspoint.txn.bmt;
import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.transaction.UserTransaction;
@Stateless
@TransactionManagement(value=TransactionManagementType.BEAN)
public class AccountBean implements AccountBeanLocal {
@Resource
private UserTransaction userTransaction;
public void transferFund(Account fromAccount, double fund ,
Account toAccount) throws Exception{
try{
userTransaction.begin();
confirmAccountDetail(fromAccount);
withdrawAmount(fromAccount,fund);
confirmAccountDetail(toAccount);
depositAmount(toAccount,fund);
userTransaction.commit();
}catch (InvalidAccountException exception) {
userTransaction.rollback();
}catch (InsufficientFundException exception) {
userTransaction.rollback();
}catch (PaymentException exception) {
userTransaction.rollback();
}
}
private void confirmAccountDetail(Account account)
throws InvalidAccountException {
}
private void withdrawAmount() throws InsufficientFundException {
}
private void depositAmount() throws PaymentException{
}
}
En este ejemplo, utilizamos UserTransaction interfaz para marcar el comienzo de la transacción usando userTransaction.begin()llamada al método. Marcamos la finalización de la transacción, utilizandouserTransaction.commit() y si ocurre alguna excepción durante la transacción, revertimos la transacción completa usando userTransaction.rollback() llamada al método.
La seguridad es una de las principales preocupaciones de cualquier aplicación de nivel empresarial. Incluye identificación de usuario (s) o sistema que accede a la aplicación. Con base en la identificación, permite o deniega el acceso a recursos dentro de la aplicación. Un contenedor EJB gestiona los problemas de seguridad estándar o se puede personalizar para manejar cualquier problema de seguridad específico.
Términos importantes de seguridad
Authentication - Este es el proceso que garantiza que el usuario que accede al sistema o la aplicación se verifica como auténtico.
Authorization - Este es el proceso que garantiza que el usuario auténtico tenga el nivel adecuado de autoridad para acceder a los recursos del sistema.
User - Usuario representa al cliente o sistema que accede a la aplicación.
User Groups - Los usuarios pueden ser parte del grupo que tiene ciertas autorizaciones, por ejemplo, el grupo de administradores.
User Roles - Los roles definen el nivel de autoridad que tiene un usuario o los permisos para acceder a un recurso del sistema.
Seguridad gestionada por contenedor
EJB 3.0 ha especificado los siguientes atributos / anotaciones de seguridad, que implementan los contenedores EJB.
DeclareRoles- Indica que la clase aceptará los roles declarados. Las anotaciones se aplican a nivel de clase.
RolesAllowed- Indica que el usuario del rol especificado puede acceder a un método. Se puede aplicar a nivel de clase, lo que da como resultado que se pueda acceder a todos los métodos de la clase comprar usuario del rol especificado.
PermitAll- Indica que un método comercial es accesible para todos. Se puede aplicar tanto a nivel de clase como de método.
DenyAll - Indica que un método comercial no es accesible para ninguno de los usuarios especificados a nivel de clase o método.
Ejemplo
package com.tutorialspoint.security.required;
import javax.ejb.*
@Stateless
@DeclareRoles({"student" "librarian"})
public class LibraryBean implements LibraryRemote {
@RolesAllowed({"librarian"})
public void delete(Book book) {
//delete book
}
@PermitAll
public void viewBook(Book book) {
//view book
}
@DenyAll
public void deleteAll() {
//delete all books
}
}
Configuración de seguridad
Asigne roles y grupos de usuarios en el archivo de configuración.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 EJB 3.0//EN" "http://www.sun.com/software/appserver/dtds/sun-ejb-jar_3_0-0.dtd">
<ejb-jar>
<security-role-mapping>
<role-name>student</role-name>
<group-name>student-group</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>librarian</role-name>
<group-name>librarian-group</group-name>
</security-role-mapping>
<enterprise-beans/>
</ejb-jar>
JNDI son las siglas de Java Naming and Directory Interface. Es un conjunto de interfaces de servicio y API. Las aplicaciones basadas en Java utilizan JNDI para servicios de directorio y nombres. En el contexto de EJB, hay dos términos.
Binding - Esto se refiere a la asignación de un nombre a un objeto EJB, que se puede utilizar más adelante.
Lookup - Esto se refiere a buscar y obtener un objeto de EJB.
En Jboss, los beans de sesión están enlazados en JNDI en el siguiente formato de forma predeterminada.
local - nombre EJB / local
remote - Nombre EJB / remoto
En caso de que EJB se incluya con el archivo <application-name> .ear, el formato predeterminado es el siguiente:
local - nombre-aplicación / nombre-ejb / local
remote - nombre-aplicación / nombre-ejb / remoto
Ejemplo de enlace predeterminado
Consulte la salida de la consola JBoss del capítulo EJB - Crear aplicación .
Salida de registro del servidor de aplicaciones JBoss
...
16:30:02,723 INFO [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibrarySessionBean,service=EJB3
16:30:02,723 INFO [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibrarySessionBean ejbName: LibrarySessionBean
16:30:02,731 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
LibrarySessionBean/remote - EJB3.x Default Remote Business Interface
LibrarySessionBean/remote-com.tutorialspoint.stateless.LibrarySessionBeanRemote - EJB3.x Remote Business Interface
...
Encuadernación personalizada
Las siguientes anotaciones se pueden utilizar para personalizar los enlaces JNDI predeterminados:
local - org.jboss.ejb3.LocalBinding
remote - org.jboss.ejb3.RemoteBindings
Actualice LibrarySessionBean.java. Consulte el capítulo EJB - Crear aplicación .
LibrarySessionBean
package com.tutorialspoint.stateless;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;
@Stateless
@LocalBinding(jndiBinding="tutorialsPoint/librarySession")
public class LibrarySessionBean implements LibrarySessionBeanLocal {
List<String> bookShelf;
public LibrarySessionBean() {
bookShelf = new ArrayList<String>();
}
public void addBook(String bookName) {
bookShelf.add(bookName);
}
public List<String> getBooks() {
return bookShelf;
}
}
BibliotecaSessionBeanLocal
package com.tutorialspoint.stateless;
import java.util.List;
import javax.ejb.Local;
@Local
public interface LibrarySessionBeanLocal {
void addBook(String bookName);
List getBooks();
}
Cree el proyecto, implemente la aplicación en Jboss y verifique el siguiente resultado en la consola de Jboss:
...
16:30:02,723 INFO [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibrarySessionBean,service=EJB3
16:30:02,723 INFO [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibrarySessionBean ejbName: LibrarySessionBean
16:30:02,731 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
tutorialsPoint/librarySession - EJB3.x Default Local Business Interface
tutorialsPoint/librarySession-com.tutorialspoint.stateless.LibrarySessionBeanLocal - EJB3.x Local Business Interface
...
EJB 3.0 ofrece la opción de definir relaciones / asignaciones de entidades de base de datos como relaciones uno a uno, uno a muchos, muchos a uno y muchos a muchos.
A continuación se muestran las anotaciones relevantes:
One-to-One- Los objetos tienen una relación de uno a uno. Por ejemplo, un pasajero puede viajar con un solo boleto a la vez.
One-to-Many- Los objetos tienen una relación de uno a varios. Por ejemplo, un padre puede tener varios hijos.
Many-to-One- Los objetos tienen una relación de varios a uno. Por ejemplo, varios niños que tienen una madre soltera.
Many-to-Many- Los objetos tienen una relación de varios a varios. Por ejemplo, un libro puede tener varios autores y un autor puede escribir varios libros.
Demostraremos el uso del mapeo ManyToMany aquí. Para representar la relación ManyToMany, se requieren tres tablas siguientes:
Book - Mesa de libros, teniendo registros de libros.
Author - Tabla de autor, teniendo registros de autor.
Book_Author - Tabla de autor del libro, con enlace de la tabla de libro y autor antes mencionada
Crear tablas
Crea una tabla book author, book_author en la base de datos predeterminada postgres.
CREATE TABLE book (
book_id integer,
name varchar(50)
);
CREATE TABLE author (
author_id integer,
name varchar(50)
);
CREATE TABLE book_author (
book_id integer,
author_id integer
);
Crear clases de entidad
@Entity
@Table(name="author")
public class Author implements Serializable{
private int id;
private String name;
...
}
@Entity
@Table(name="book")
public class Book implements Serializable{
private int id;
private String title;
private Set<Author> authors;
...
}
Utilice la anotación ManyToMany en la entidad del libro.
@Entity
public class Book implements Serializable{
...
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}
, fetch = FetchType.EAGER)
@JoinTable(table = @Table(name = "book_author"),
joinColumns = {@JoinColumn(name = "book_id")},
inverseJoinColumns = {@JoinColumn(name = "author_id")})
public Set<Author> getAuthors() {
return authors;
}
...
}
Aplicación de ejemplo
Creemos una aplicación EJB de prueba para probar objetos de relaciones entre entidades en EJB 3.0.
Paso | Descripción |
---|---|
1 | Cree un proyecto con un nombre EjbComponent en un paquete com.tutorialspoint.entity como se explica en el capítulo EJB - Crear aplicación . Utilice el proyecto creado en el capítulo EJB - Persistencia como tal para este capítulo para comprender los objetos incrustados en los conceptos de EJB. |
2 | Cree Author.java en el paquete com.tutorialspoint.entity como se explica en el capítulo EJB - Crear aplicación . Mantenga el resto de los archivos sin cambios. |
3 | Cree Book.java en el paquete com.tutorialspoint.entity . Utilice el capítulo EJB - Persistencia como referencia. Mantenga el resto de los archivos sin cambios. |
4 | Limpie y compile la aplicación para asegurarse de que la lógica empresarial funcione según los requisitos. |
5 | Finalmente, implemente la aplicación en forma de archivo jar en JBoss Application Server. El servidor de aplicaciones JBoss se iniciará automáticamente si aún no se ha iniciado. |
6 | Ahora cree el cliente EJB, una aplicación basada en consola de la misma manera que se explica en el capítulo EJB - Crear aplicación en el temaCreate Client to access EJB. |
EJBComponent (módulo EJB)
Autor.java
package com.tutorialspoint.entity;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="author")
public class Author implements Serializable{
private int id;
private String name;
public Author() {}
public Author(int id, String name) {
this.id = id;
this.name = name;
}
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
@Column(name="author_id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return id + "," + name;
}
}
Book.java
package com.tutorialspoint.entity;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
@Entity
@Table(name="book")
public class Book implements Serializable{
private int id;
private String name;
private Set<Author> authors;
public Book() {
}
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
@Column(name="book_id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setAuthors(Set<Author> authors) {
this.authors = authors;
}
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}
, fetch = FetchType.EAGER)
@JoinTable(table = @Table(name = "book_author"),
joinColumns = {@JoinColumn(name = "book_id")},
inverseJoinColumns = {@JoinColumn(name = "author_id")})
public Set<Author> getAuthors() {
return authors;
}
}
LibraryPersistentBeanRemote.java
package com.tutorialspoint.stateless;
import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Remote;
@Remote
public interface LibraryPersistentBeanRemote {
void addBook(Book bookName);
List<Book> getBooks();
}
LibraryPersistentBean.java
package com.tutorialspoint.stateless;
import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
public LibraryPersistentBean() {
}
@PersistenceContext(unitName="EjbComponentPU")
private EntityManager entityManager;
public void addBook(Book book) {
entityManager.persist(book);
}
public List<Book> getBooks() {
return entityManager.createQuery("From Book").getResultList();
}
}
Tan pronto como implemente el proyecto EjbComponent en JBOSS, observe el registro de jboss.
JBoss ha creado automáticamente una entrada JNDI para nuestro bean de sesión - LibraryPersistentBean/remote.
Usaremos esta cadena de búsqueda para obtener un objeto comercial remoto de tipo: com.tutorialspoint.interceptor.LibraryPersistentBeanRemote
Salida de registro del servidor de aplicaciones JBoss
...
16:30:01,401 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
LibraryPersistentBean/remote-com.tutorialspoint.interceptor.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryPersistentBean,service=EJB3
16:30:02,723 INFO [EJBContainer] STARTED EJB: com.tutorialspoint.interceptor.LibraryPersistentBeanRemote ejbName: LibraryPersistentBean
16:30:02,731 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
LibraryPersistentBean/remote-com.tutorialspoint.interceptor.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
...
EJBTester (cliente EJB)
jndi.properties
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
Estas propiedades se utilizan para inicializar el objeto InitialContext del servicio de nombres de Java.
El objeto InitialContext se utilizará para buscar un bean de sesión sin estado.
EJBTester.java
package com.tutorialspoint.test;
import com.tutorialspoint.stateful.LibraryBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class EJBTester {
BufferedReader brConsoleReader = null;
Properties props;
InitialContext ctx;
{
props = new Properties();
try {
props.load(new FileInputStream("jndi.properties"));
} catch (IOException ex) {
ex.printStackTrace();
}
try {
ctx = new InitialContext(props);
} catch (NamingException ex) {
ex.printStackTrace();
}
brConsoleReader =
new BufferedReader(new InputStreamReader(System.in));
}
public static void main(String[] args) {
EJBTester ejbTester = new EJBTester();
ejbTester.testEmbeddedObjects();
}
private void showGUI() {
System.out.println("**********************");
System.out.println("Welcome to Book Store");
System.out.println("**********************");
System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
}
private void testEmbeddedObjects() {
try {
int choice = 1;
LibraryPersistentBeanRemote libraryBean =
(LibraryPersistentBeanRemote)
ctx.lookup("LibraryPersistentBean/remote");
while (choice != 2) {
String bookName;
String authorName;
showGUI();
String strChoice = brConsoleReader.readLine();
choice = Integer.parseInt(strChoice);
if (choice == 1) {
System.out.print("Enter book name: ");
bookName = brConsoleReader.readLine();
System.out.print("Enter author name: ");
authorName = brConsoleReader.readLine();
Book book = new Book();
book.setName(bookName);
Author author = new Author();
author.setName(authorName);
Set<Author> authors = new HashSet<Author>();
authors.add(author);
book.setAuthors(authors);
libraryBean.addBook(book);
} else if (choice == 2) {
break;
}
}
List<Book> booksList = libraryBean.getBooks();
System.out.println("Book(s) entered so far: " + booksList.size());
int i = 0;
for (Book book:booksList) {
System.out.println((i+1)+". " + book.getName());
System.out.print("Author: ");
Author[] authors = (Author[])books.getAuthors().toArray();
for(int j=0;j<authors.length;j++) {
System.out.println(authors[j]);
}
i++;
}
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}finally {
try {
if(brConsoleReader !=null) {
brConsoleReader.close();
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}
}
EJBTester realiza las siguientes tareas:
Cargue las propiedades de jndi.properties e inicialice el objeto InitialContext.
En el método testInterceptedEjb (), la búsqueda de jndi se realiza con el nombre - "LibraryPersistenceBean / remote" para obtener el objeto comercial remoto (EJB sin estado).
Luego, se muestra al usuario una interfaz de usuario de la tienda de la biblioteca y se le pide que ingrese una opción.
Si el usuario ingresa 1, el sistema solicita el nombre del libro y guarda el libro usando el método addBook () del bean de sesión sin estado. Session Bean está almacenando el libro en la base de datos.
Si el usuario ingresa 2, el sistema recupera libros usando el método getBooks () del bean de sesión sin estado y sale.
Ejecute el cliente para acceder a EJB
Busque EJBTester.java en el explorador de proyectos. Haga clic derecho en la clase EJBTester y seleccionerun file.
Verifique la siguiente salida en la consola de Netbeans.
run:
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 1
Enter book name: learn html5
Enter Author name: Robert
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 2
Book(s) entered so far: 1
1. learn html5
Author: Robert
BUILD SUCCESSFUL (total time: 21 seconds)
En EJB 3.0, el mecanismo de persistencia se usa para acceder a la base de datos en la que el contenedor administra las operaciones relacionadas con la base de datos. Los desarrolladores pueden acceder a la base de datos mediante la llamada a la API de JDBC directamente en los métodos comerciales de EJB.
Para demostrar el acceso a la base de datos en EJB, debemos realizar las siguientes tareas:
Step 1 - Crea una tabla en la base de datos.
Step 2 - Crear un EJB apátrida teniendo negocios conmigo.
Step 3- Actualización de EJB sin estado. Agregue métodos para agregar registros y obtener registros de la base de datos a través del administrador de entidades.
Step 4 - Un cliente de aplicación basado en consola accederá al EJB sin estado para conservar los datos en la base de datos.
Crear mesa
Crea una tabla books en la base de datos predeterminada postgres.
CREATE TABLE books (
id integer PRIMARY KEY,
name varchar(50)
);
Crear una clase de modelo
public class Book implements Serializable{
private int id;
private String name;
public Book() {
}
public int getId() {
return id;
}
...
}
Crear EJB sin estado
@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
public void addBook(Book book) {
//persist book using jdbc calls
}
public List<Book> getBooks() {
//get books using jdbc calls
}
...
}
Después de construir el módulo EJB, necesitamos un cliente para acceder al bean sin estado, que crearemos en la siguiente sección.
Aplicación de ejemplo
Creemos una aplicación EJB de prueba para probar el mecanismo de acceso a la base de datos EJB.
Paso | Descripción |
---|---|
1 | Cree un proyecto con un nombre EjbComponent en un paquete com.tutorialspoint.entity como se explica en el capítulo EJB - Crear aplicación . También puede utilizar el proyecto creado en el capítulo EJB - Crear aplicación como tal para este capítulo para comprender los conceptos de acceso a datos de EJB. |
2 | Cree Book.java en el paquete com.tutorialspoint.entity y modifíquelo como se muestra a continuación. |
3 | Cree LibraryPersistentBean.java y LibraryPersistentBeanRemote como se explica en el capítulo EJB - Crear aplicación y modifíquelos como se muestra a continuación. |
4 | Limpie y compile la aplicación para asegurarse de que la lógica empresarial funcione según los requisitos. |
5 | Finalmente, implemente la aplicación en forma de archivo jar en JBoss Application Server. El servidor de aplicaciones JBoss se iniciará automáticamente si aún no se ha iniciado. |
6 | Ahora cree el cliente EJB, una aplicación basada en consola de la misma manera que se explica en el capítulo EJB - Crear aplicación en el temaCreate Client to access EJB. Modifíquelo como se muestra a continuación. |
EJBComponent (módulo EJB)
Book.java
package com.tutorialspoint.entity;
import java.io.Serializable;
public class Book implements Serializable{
private int id;
private String name;
public Book() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
LibraryPersistentBeanRemote.java
package com.tutorialspoint.stateless;
import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Remote;
@Remote
public interface LibraryPersistentBeanRemote {
void addBook(Book bookName);
List<Book> getBooks();
}
LibraryPersistentBean.java
package com.tutorialspoint.stateless;
import com.tutorialspoint.entity.Book;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;
@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
public LibraryPersistentBean() {
}
public void addBook(Book book) {
Connection con = null;
String url = "jdbc:postgresql://localhost:5432/postgres";
String driver = "org.postgresql.driver";
String userName = "sa";
String password = "sa";
List<Book> books = new ArrayList<Book>();
try {
Class.forName(driver).newInstance();
con = DriverManager.getConnection(url , userName, password);
PreparedStatement st =
con.prepareStatement("insert into book(name) values(?)");
st.setString(1,book.getName());
int result = st.executeUpdate();
} catch (SQLException ex) {
ex.printStackTrace();
} catch (InstantiationException ex) {
ex.printStackTrace();
} catch (IllegalAccessException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
}
public List<Book> getBooks() {
Connection con = null;
String url = "jdbc:postgresql://localhost:5432/postgres";
String driver = "org.postgresql.driver";
String userName = "sa";
String password = "sa";
List<Book> books = new ArrayList<Book>();
try {
Class.forName(driver).newInstance();
con = DriverManager.getConnection(url , userName, password);
Statement st = con.createStatement();
ResultSet rs = st.executeQuery("select * from book");
Book book;
while (rs.next()) {
book = new Book();
book.setId(rs.getInt(1));
book.setName(rs.getString(2));
books.add(book);
}
} catch (SQLException ex) {
ex.printStackTrace();
} catch (InstantiationException ex) {
ex.printStackTrace();
} catch (IllegalAccessException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
return books;
}
}
Tan pronto como implemente el proyecto EjbComponent en JBOSS, observe el registro de jboss.
JBoss ha creado automáticamente una entrada JNDI para nuestro bean de sesión - LibraryPersistentBean/remote.
Usaremos esta cadena de búsqueda para obtener un objeto comercial remoto de tipo: com.tutorialspoint.stateless.LibraryPersistentBeanRemote
Salida de registro del servidor de aplicaciones JBoss
...
16:30:01,401 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
LibraryPersistentBean/remote-com.tutorialspoint.stateless.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryPersistentBeanRemote,service=EJB3
16:30:02,723 INFO [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibraryPersistentBeanRemote ejbName: LibraryPersistentBean
16:30:02,731 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
LibraryPersistentBean/remote-com.tutorialspoint.stateless.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
...
EJBTester (cliente EJB)
jndi.properties
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
Estas propiedades se utilizan para inicializar el objeto InitialContext del servicio de nombres de Java.
El objeto InitialContext se utilizará para buscar un bean de sesión sin estado.
EJBTester.java
package com.tutorialspoint.test;
import com.tutorialspoint.stateless.LibraryPersistentBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class EJBTester {
BufferedReader brConsoleReader = null;
Properties props;
InitialContext ctx;
{
props = new Properties();
try {
props.load(new FileInputStream("jndi.properties"));
} catch (IOException ex) {
ex.printStackTrace();
}
try {
ctx = new InitialContext(props);
} catch (NamingException ex) {
ex.printStackTrace();
}
brConsoleReader =
new BufferedReader(new InputStreamReader(System.in));
}
public static void main(String[] args) {
EJBTester ejbTester = new EJBTester();
ejbTester.testEntityEjb();
}
private void showGUI() {
System.out.println("**********************");
System.out.println("Welcome to Book Store");
System.out.println("**********************");
System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
}
private void testEntityEjb() {
try {
int choice = 1;
LibraryPersistentBeanRemote libraryBean =
LibraryPersistentBeanRemote)
ctx.lookup("LibraryPersistentBean/remote");
while (choice != 2) {
String bookName;
showGUI();
String strChoice = brConsoleReader.readLine();
choice = Integer.parseInt(strChoice);
if (choice == 1) {
System.out.print("Enter book name: ");
bookName = brConsoleReader.readLine();
Book book = new Book();
book.setName(bookName);
libraryBean.addBook(book);
} else if (choice == 2) {
break;
}
}
List<Book> booksList = libraryBean.getBooks();
System.out.println("Book(s) entered so far: " + booksList.size());
int i = 0;
for (Book book:booksList) {
System.out.println((i+1)+". " + book.getName());
i++;
}
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}finally {
try {
if(brConsoleReader !=null) {
brConsoleReader.close();
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}
}
EJBTester realiza las siguientes tareas:
Cargue las propiedades de jndi.properties e inicialice el objeto InitialContext.
En el método testStatefulEjb (), la búsqueda de jndi se realiza con el nombre - "LibraryStatelessSessionBean / remote" para obtener el objeto de negocio remoto (EJB con estado).
Luego, se muestra al usuario una interfaz de usuario de la tienda de la biblioteca y se le solicita que ingrese una opción.
Si el usuario ingresa 1, el sistema solicita el nombre del libro y guarda el libro usando el método addBook () del bean de sesión sin estado. Session Bean mantiene el libro en la base de datos a través de la llamada EntityManager.
Si el usuario ingresa 2, el sistema recupera libros usando el método getBooks () del bean de sesión sin estado y sale.
Luego, se realiza otra búsqueda de jndi con el nombre - "LibraryStatelessSessionBean / remote" para obtener el objeto comercial remoto (EJB con estado) nuevamente y se realiza la lista de libros.
Ejecute el cliente para acceder a EJB
Busque EJBTester.java en el explorador de proyectos. Haga clic derecho en la clase EJBTester y seleccionerun file.
Verifique la siguiente salida en la consola de Netbeans.
run:
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 1
Enter book name: Learn Java
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 2
Book(s) entered so far: 1
1. learn java
BUILD SUCCESSFUL (total time: 15 seconds)
EJB Query LanguageEs muy útil escribir consultas personalizadas sin preocuparse por los detalles subyacentes de la base de datos. Es bastante similar a HQL, lenguaje de consulta de hibernación y a menudo se le conoce con el nombre EJBQL.
Para demostrar EJBQL en EJB, realizaremos las siguientes tareas:
Step 1 - Crear tabla en base de datos.
Step 2 - Crear un EJB apátrida teniendo negocios conmigo.
Step 3−Actualizar EJB sin estado. Agregue métodos para agregar registros y obtener registros de la base de datos a través del administrador de entidades.
Step 4 - Un cliente de aplicación basado en consola accederá al EJB sin estado para conservar los datos en la base de datos.
Crear mesa
Crea una tabla books en la base de datos predeterminada postgres.
CREATE TABLE books (
id integer PRIMARY KEY,
name varchar(50)
);
Crear una clase de modelo
public class Book implements Serializable{
private int id;
private String name;
public Book() {
}
public int getId() {
return id;
}
...
}
Crear EJB sin estado
@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
public void addBook(Book book) {
//persist book using entity manager
}
public List<Book> getBooks() {
//get books using entity manager
}
...
}
Después de construir el módulo EJB, necesitamos un cliente para acceder al bean sin estado, que crearemos en la siguiente sección.
Aplicación de ejemplo
Creemos una aplicación EJB de prueba para probar el mecanismo de acceso a la base de datos EJB.
Paso | Descripción |
---|---|
1 | Cree un proyecto con un nombre EjbComponent en un paquete com.tutorialspoint.entity como se explica en el capítulo EJB - Crear aplicación . También puede utilizar el proyecto creado en el capítulo EJB - Crear aplicación como tal para este capítulo para comprender los conceptos de acceso a datos de EJB. |
2 | Cree Book.java en el paquete com.tutorialspoint.entity y modifíquelo como se muestra a continuación. |
3 | Cree LibraryPersistentBean.java y LibraryPersistentBeanRemote como se explica en el capítulo EJB - Crear aplicación y modifíquelos como se muestra a continuación. |
4 | Limpie y compile la aplicación para asegurarse de que la lógica empresarial funcione según los requisitos. |
5 | Finalmente, implemente la aplicación en forma de archivo jar en JBoss Application Server. El servidor de aplicaciones JBoss se iniciará automáticamente si aún no se ha iniciado. |
6 | Ahora cree el cliente EJB, una aplicación basada en consola de la misma manera que se explica en el capítulo EJB - Crear aplicación en el temaCreate Client to access EJB. Modifíquelo como se muestra a continuación. |
EJBComponent (módulo EJB)
Book.java
package com.tutorialspoint.entity;
import java.io.Serializable;
public class Book implements Serializable{
private int id;
private String name;
public Book() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
LibraryPersistentBeanRemote.java
package com.tutorialspoint.stateless;
import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Remote;
@Remote
public interface LibraryPersistentBeanRemote {
void addBook(Book bookName);
List<Book> getBooks();
}
LibraryPersistentBean.java
package com.tutorialspoint.stateless;
import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
public LibraryPersistentBean() {
}
@PersistenceContext(unitName="EntityEjbPU")
private EntityManager entityManager;
public void addBook(Book book) {
entityManager.persist(book);
}
public List<Book> getBooks() {
//create an ejbql expression
String ejbQL = "From Book b where b.name like ?1";
//create query
Query query = entityManager.createQuery(ejbQL);
//substitute parameter.
query.setParameter(1, "%test%");
//execute the query
return query.getResultList();
}
}
Tan pronto como implemente el proyecto EjbComponent en JBOSS, observe el registro de jboss.
JBoss ha creado automáticamente una entrada JNDI para nuestro bean de sesión - LibraryPersistentBean/remote.
Usaremos esta cadena de búsqueda para obtener un objeto comercial remoto de tipo: com.tutorialspoint.stateless.LibraryPersistentBeanRemote
Salida de registro del servidor de aplicaciones JBoss
...
16:30:01,401 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
LibraryPersistentBean/remote-com.tutorialspoint.stateless.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryPersistentBeanRemote,service=EJB3
16:30:02,723 INFO [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibraryPersistentBeanRemote ejbName: LibraryPersistentBean
16:30:02,731 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
LibraryPersistentBean/remote-com.tutorialspoint.stateless.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
...
EJBTester (cliente EJB)
jndi.properties
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
Estas propiedades se utilizan para inicializar el objeto InitialContext del servicio de nombres de Java.
El objeto InitialContext se utilizará para buscar un bean de sesión sin estado.
EJBTester.java
package com.tutorialspoint.test;
import com.tutorialspoint.stateless.LibraryPersistentBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class EJBTester {
BufferedReader brConsoleReader = null;
Properties props;
InitialContext ctx;
{
props = new Properties();
try {
props.load(new FileInputStream("jndi.properties"));
} catch (IOException ex) {
ex.printStackTrace();
}
try {
ctx = new InitialContext(props);
} catch (NamingException ex) {
ex.printStackTrace();
}
brConsoleReader =
new BufferedReader(new InputStreamReader(System.in));
}
public static void main(String[] args) {
EJBTester ejbTester = new EJBTester();
ejbTester.testEntityEjb();
}
private void showGUI() {
System.out.println("**********************");
System.out.println("Welcome to Book Store");
System.out.println("**********************");
System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
}
private void testEntityEjb() {
try {
int choice = 1;
LibraryPersistentBeanRemote libraryBean =
LibraryPersistentBeanRemote)
ctx.lookup("LibraryPersistentBean/remote");
while (choice != 2) {
String bookName;
showGUI();
String strChoice = brConsoleReader.readLine();
choice = Integer.parseInt(strChoice);
if (choice == 1) {
System.out.print("Enter book name: ");
bookName = brConsoleReader.readLine();
Book book = new Book();
book.setName(bookName);
libraryBean.addBook(book);
} else if (choice == 2) {
break;
}
}
List<Book> booksList = libraryBean.getBooks();
System.out.println("Book(s) entered so far: " + booksList.size());
int i = 0;
for (Book book:booksList) {
System.out.println((i+1)+". " + book.getName());
i++;
}
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}finally {
try {
if(brConsoleReader !=null) {
brConsoleReader.close();
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}
}
EJBTester realiza las siguientes tareas:
Cargue las propiedades de jndi.properties e inicialice el objeto InitialContext.
En el método testStatefulEjb (), la búsqueda de jndi se realiza con el nombre - "LibraryStatelessSessionBean / remote" para obtener el objeto de negocio remoto (ejb con estado).
Luego, se muestra al usuario una interfaz de usuario de la tienda de la biblioteca y se le solicita que ingrese una opción.
Si el usuario ingresa 1, el sistema solicita el nombre del libro y guarda el libro usando el método addBook () del bean de sesión sin estado. Session Bean mantiene el libro en la base de datos a través de la llamada EntityManager.
Si el usuario ingresa 2, el sistema recupera libros usando el método getBooks () del bean de sesión sin estado y sale.
Luego, se realiza otra búsqueda de jndi con el nombre - "LibraryStatelessSessionBean / remote" para obtener el objeto comercial remoto (EJB con estado) nuevamente y se realiza la lista de libros.
Ejecute el cliente para acceder a EJB
Busque EJBTester.java en el explorador de proyectos. Haga clic derecho en la clase EJBTester y seleccionerun file.
Verifique la siguiente salida en la consola de Netbeans.
run:
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 1
Enter book name: Learn Testing
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 2
Book(s) entered so far: 1
1. learn Testing
BUILD SUCCESSFUL (total time: 15 seconds)
Los EJB forman parte de las aplicaciones empresariales que normalmente se basan en entornos distribuidos. Por lo tanto, además de las excepciones normales que pueden ocurrir, puede haber excepciones como fallas de comunicación, permisos de seguridad, servidor inactivo, etc.
El contenedor EJB considera las excepciones de dos maneras:
Application Exception - Si se infringe la regla de negocio o se produce una excepción al ejecutar la lógica de negocio.
System Exception- Cualquier excepción, que no sea causada por la lógica empresarial o el código empresarial. RuntimeException, RemoteException son SystemException. Por ejemplo, error durante la búsqueda de EJB. RuntimeException, RemoteException son SystemException.
¿Cómo maneja EJB Container las excepciones?
Cuando Application Exceptionocurre, el contenedor EJB intercepta la excepción, pero devuelve al cliente lo mismo tal como está. No revierte la transacción a menos que se especifique en el código mediante el método EJBContext.setRollBackOnly (). EJB Container no incluye la excepción en caso de excepción de aplicación.
Cuando System Exceptionocurre, el contenedor EJB intercepta la excepción, revierte la transacción e inicia las tareas de limpieza. Envuelve la excepción en RemoteException y la envía al cliente.
Manejo de la excepción de la aplicación
Las excepciones de aplicaciones generalmente se lanzan en los métodos Session EJB, ya que estos son los métodos responsables de ejecutar la lógica empresarial. La excepción de la aplicación debe declararse en la cláusula throws del método comercial y debe lanzarse en caso de que falle la lógica empresarial.
@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
...
public List<Book> getBooks() throws NoBookAvailableException {
List<Book> books =
entityManager.createQuery("From Books").getResultList();
if(books.size == 0)
throw NoBookAvailableException
("No Book available in library.");
return books;
}
...
}
Excepción del sistema de manejo
La excepción del sistema puede ocurrir en cualquier momento, ya que falla la búsqueda de nombres, se produce un error de SQL al obtener datos. En tal caso, dicha excepción debe incluirse en EJBException y devolverse al cliente.
@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
...
public List<Book> getBooks() {
try {
List<Book> books =
entityManager.createQuery("From Books").getResultList();
} catch (CreateException ce) {
throw (EJBException) new EJBException(ce).initCause(ce);
} catch (SqlException se) {
throw (EJBException) new EJBException(se).initCause(se);
}
return books;
}
...
}
En el lado del cliente, maneje la EJBException.
public class EJBTester {
private void testEntityEjb() {
...
try{
LibraryPersistentBeanRemote libraryBean =
LibraryPersistentBeanRemote)ctx.lookup("LibraryPersistentBean/remote");
List<Book> booksList = libraryBean.getBooks();
} catch(EJBException e) {
Exception ne = (Exception) e.getCause();
if(ne.getClass().getName().equals("SqlException")) {
System.out.println("Database error: "+ e.getMessage());
}
}
...
}
}
EJB 3.0 proporciona una opción para exponer la sesión EJB como un servicio web. La anotación @WebService se usa para marcar una clase como un punto final del servicio web y @WebMethod se usa para exponer un método como método web al cliente.
@Stateless
@WebService(serviceName="LibraryService")
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
...
@WebMethod(operationName="getBooks")
public List<Book> getBooks() {
return entityManager.createQuery("From Books").getResultList();
}
...
}
Aplicación de ejemplo
Creemos una aplicación EJB de prueba para probar la compatibilidad con blob / clob en EJB 3.0.
Paso | Descripción |
---|---|
1 | Cree un proyecto con un nombre EjbComponent en un paquete com.tutorialspoint.entity como se explica en el capítulo EJB - Crear aplicación. Utilice el proyecto creado en el capítulo EJB - Persistencia como tal para este capítulo para comprender los objetos clob / blob en los conceptos de EJB. |
2 | Cree LibraryPersistentBean.java en el paquete com.tutorialspoint.stateless. Utilice el capítulo EJB - Persistencia como referencia. Mantenga el resto de los archivos sin cambios. |
3 | Limpie y compile la aplicación para asegurarse de que la lógica empresarial funcione según los requisitos. |
4 | Finalmente, implemente la aplicación en forma de archivo jar en JBoss Application Server. El servidor de aplicaciones JBoss se iniciará automáticamente si aún no se ha iniciado. |
LibraryPersistentBean.java
package com.tutorialspoint.stateless;
import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Stateless;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@Stateless
@WebService(serviceName="LibraryService")
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
public LibraryPersistentBean() {
}
@PersistenceContext(unitName="EjbComponentPU")
private EntityManager entityManager;
public void addBook(Book book) {
entityManager.persist(book);
}
@WebMethod(operationName="getBooks")
public List <Book> getBooks() {
return entityManager.createQuery("From Book").getResultList();
}
}
Salida de registro del servidor de aplicaciones JBoss
10:51:37,271 INFO [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibraryPersistentBean ejbName: LibraryPersistentBean
10:51:37,287 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
LibraryPersistentBean/remote-com.tutorialspoint.stateless.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
10:51:37,349 INFO [EJBContainer] STARTED EJB: com.tuturialspoint.messagebean.LibraryMessageBean ejbName: BookMessageHandler
10:51:37,443 INFO [DefaultEndpointRegistry] register: jboss.ws:context=EjbComponent,endpoint=LibraryPersistentBean
10:51:38,191 INFO [WSDLFilePublisher] WSDL published to: file:/D:/Jboss-5.0.1/server/default/data/wsdl/EjbComponent.jar/
LibraryService3853081455302946642.wsdl
Crear cliente para acceder a EJB como servicio web
En NetBeans IDE, seleccione ,File > New Project >.Seleccione el tipo de proyecto en la categoría,Java, Tipo de proyecto como Java Application. Hacer clicNext >Ingrese el nombre y la ubicación del proyecto. Hacer clicFinish >botón. Hemos elegido el nombre como EJBWebServiceClient.
Haga clic derecho en el nombre del proyecto en la ventana del Explorador de proyectos. SeleccioneNew > WebService Client.
Agregue el LibraryPersistentBean del proyecto del componente EJB creado anteriormente en WSDL y la ubicación del cliente usando Add Project botón en compile lengüeta.
Haga clic en el botón Finalizar. Verifique la siguiente estructura en el explorador de proyectos.
Cree EJBWebServiceClient.java
package ejbwebserviceclient;
public class EJBWebServiceClient {
public static void main(String[] args) {
}
}
Seleccione el método web getBooks del servicio web como se muestra en la figura siguiente y arrástrelo a la ventana de código de EJBWebServiceClient.
Verá una salida similar a la que se muestra a continuación.
Actualice el código EJBWebServiceClient para utilizar este método.
package ejbwebserviceclient;
public class EJBWebServiceClient {
public static void main(String[] args) {
for(com.tutorialspoint.stateless.Book book:getBooks()) {
System.out.println(book.getName());
}
}
private static java.util.List
<com.tutorialspoint.stateless.Book> getBooks() {
com.tutorialspoint.stateless.LibraryService service =
new com.tutorialspoint.stateless.LibraryService();
com.tutorialspoint.stateless.LibraryPersistentBean port =
service.getLibraryPersistentBeanPort();
return port.getBooks();
}
}
Ejecutar el cliente
Haga clic derecho en el nombre del proyecto en la ventana del Explorador de proyectos. SeleccioneRun. Netbeans construirá el cliente y lo ejecutará. Verifique la siguiente salida.
ant -f D:\\SVN\\EJBWebServiceClient run
init:
Deleting: D:\SVN\EJBWebServiceClient\build\built-jar.properties
deps-jar:
Updating property file: D:\SVN\EJBWebServiceClient\build\built-jar.properties
wsimport-init:
wsimport-client-LibraryPersistentBean:
files are up to date
classLoader = java.net.URLClassLoader@4ce46c
SharedSecrets.getJavaNetAccess()=java.net.URLClassLoader$7@182cdac
wsimport-client-generate:
Compiling 1 source file to D:\SVN\EJBWebServiceClient\build\classes
compile:
run:
learn java
Learn Spring
learn JSF
Learn HTML
Learn JBoss
Learn EJB
Learn Hibernate
Learn IBatis
Times Now
learn html5
Learn images
Learn Testing
Forbes
test1
BUILD SUCCESSFUL (total time: 1 second)
Los requisitos de las aplicaciones de empaquetado que utilizan EJB 3.0 son similares a los de la plataforma J2EE. Los componentes EJB se empaquetan en módulos como archivos jar y se empaquetan en el archivo empresarial de la aplicación como archivo ear.
Hay principalmente tres componentes de cualquier aplicación empresarial:
jar - Aplicación Java aRchive, que contiene módulos EJB, módulos de cliente EJB y módulos de utilidades.
war - Aplicación web aRchive, que contiene módulos web.
ear - Aplicación empresarial aRchive, que contiene frascos y módulo de guerra.
En NetBeans, es muy fácil crear, desarrollar, empaquetar e implementar las aplicaciones J2EE.
En NetBeans IDE, seleccione,File > New Project >.Seleccione el tipo de proyecto en la categoría,Java EE, Tipo de proyecto como Enterprise Application. Hacer clicNext >botón. Ingrese el nombre y la ubicación del proyecto. Hacer clicFinish >botón. Hemos elegido el nombre como EnterpriseApplicaton.
Seleccione Servidor y configuración. MantenerCreate EJB Module y Create Web Application Modulecomprobado con los nombres predeterminados proporcionados. Haga clic en el botón finalizar. NetBeans creará la siguiente estructura en la ventana del proyecto.
Haga clic derecho en el proyecto Enterprise Application en el explorador de proyectos y seleccione Construir.
ant -f D:\\SVN\\EnterpriseApplication dist
pre-init:
init-private:
init-userdir:
init-user:
init-project:
do-init:
post-init:
init-check:
init:
deps-jar:
deps-j2ee-archive:
EnterpriseApplication-ejb.init:
EnterpriseApplication-ejb.deps-jar:
EnterpriseApplication-ejb.compile:
EnterpriseApplication-ejb.library-inclusion-in-manifest:
Building jar: D:\SVN\EnterpriseApplication\EnterpriseApplication-ejb\dist\EnterpriseApplication-ejb.jar
EnterpriseApplication-ejb.dist-ear:
EnterpriseApplication-war.init:
EnterpriseApplication-war.deps-module-jar:
EnterpriseApplication-war.deps-ear-jar:
EnterpriseApplication-ejb.init:
EnterpriseApplication-ejb.deps-jar:
EnterpriseApplication-ejb.compile:
EnterpriseApplication-ejb.library-inclusion-in-manifest:
EnterpriseApplication-ejb.dist-ear:
EnterpriseApplication-war.deps-jar:
EnterpriseApplication-war.library-inclusion-in-archive:
EnterpriseApplication-war.library-inclusion-in-manifest:
EnterpriseApplication-war.compile:
EnterpriseApplication-war.compile-jsps:
EnterpriseApplication-war.do-ear-dist:
Building jar: D:\SVN\EnterpriseApplication\EnterpriseApplication-war\dist\EnterpriseApplication-war.war
EnterpriseApplication-war.dist-ear:
pre-pre-compile:
pre-compile:
Copying 1 file to D:\SVN\EnterpriseApplication\build
Copying 1 file to D:\SVN\EnterpriseApplication\build
do-compile:
post-compile:
compile:
pre-dist:
do-dist-without-manifest:
do-dist-with-manifest:
Building jar: D:\SVN\EnterpriseApplication\dist\EnterpriseApplication.ear
post-dist:
dist:
BUILD SUCCESSFUL (total time: 1 second)
Aquí puede ver que Netbeans prepara Jar primero, luego War y al final, el archivo ear que lleva el jar y el archivo war. Cada frasco, guerra y lima de oído lleva unmeta-inf carpeta para tener metadatos según la especificación J2EE.