Учебники

EJB — Краткое руководство

EJB — Обзор

EJB означает Enterprise Java Beans . EJB является неотъемлемой частью платформы J2EE. Платформа J2EE имеет компонентную архитектуру для предоставления многоуровневых, распределенных и высокотранзакционных функций для приложений уровня предприятия.

EJB предоставляет архитектуру для разработки и развертывания корпоративных приложений на основе компонентов с учетом надежности, высокой масштабируемости и высокой производительности. Приложение EJB может быть развернуто на любом сервере приложений, соответствующем стандартной спецификации J2EE 1.3.

Мы будем подробно обсуждать EJB 3.0 в этом руководстве.

Типы

EJB в основном делится на три категории; В следующей таблице перечислены их имена с краткими описаниями —

S.No Тип и описание
1

Сеанс Бин

Сессионный компонент хранит данные конкретного пользователя за один сеанс. Это может быть с состоянием или без гражданства . Он менее ресурсоемок по сравнению с компонентом управления данными. Сессионный компонент уничтожается, как только завершается сеанс пользователя.

2

Entity Bean

Бины сущностей представляют собой постоянное хранилище данных. Пользовательские данные могут быть сохранены в базе данных с помощью объектных компонентов, а затем могут быть получены из базы данных в объектном компоненте.

3

Бин, управляемый сообщениями

Управляемые сообщениями компоненты используются в контексте JMS (Java Messaging Service). Компоненты, управляемые сообщениями, могут получать сообщения JMS от внешних объектов и действовать соответственно.

Сеанс Бин

Сессионный компонент хранит данные конкретного пользователя за один сеанс. Это может быть с состоянием или без гражданства . Он менее ресурсоемок по сравнению с компонентом управления данными. Сессионный компонент уничтожается, как только завершается сеанс пользователя.

Entity Bean

Бины сущностей представляют собой постоянное хранилище данных. Пользовательские данные могут быть сохранены в базе данных с помощью объектных компонентов, а затем могут быть получены из базы данных в объектном компоненте.

Бин, управляемый сообщениями

Управляемые сообщениями компоненты используются в контексте JMS (Java Messaging Service). Компоненты, управляемые сообщениями, могут получать сообщения JMS от внешних объектов и действовать соответственно.

Выгоды

Ниже приведены важные преимущества EJB —

  • Упрощенная разработка крупномасштабного приложения уровня предприятия.

  • Контейнер сервера приложений / EJB предоставляет большинство служб системного уровня, таких как обработка транзакций, ведение журнала, балансировка нагрузки, механизм сохранения, обработка исключений и так далее. Разработчик должен ориентироваться только на бизнес-логику приложения.

  • Контейнер EJB управляет жизненным циклом экземпляров EJB, поэтому разработчику не нужно беспокоиться о том, когда создавать / удалять объекты EJB.

Упрощенная разработка крупномасштабного приложения уровня предприятия.

Контейнер сервера приложений / EJB предоставляет большинство служб системного уровня, таких как обработка транзакций, ведение журнала, балансировка нагрузки, механизм сохранения, обработка исключений и так далее. Разработчик должен ориентироваться только на бизнес-логику приложения.

Контейнер EJB управляет жизненным циклом экземпляров EJB, поэтому разработчику не нужно беспокоиться о том, когда создавать / удалять объекты EJB.

EJB — Настройка среды

EJB — это фреймворк для Java, поэтому самым первым требованием является установка J ava Dvelopment K it (JDK) на вашем компьютере.

Системные требования

JDK 1,5 или выше.
объем памяти нет минимальных требований.
Дисковое пространство нет минимальных требований.
Операционная система нет минимальных требований.

Шаг 1 — Проверьте установку Java в вашей системе

Теперь откройте консоль и выполните следующую команду Java .

Операционные системы задача команда
Windows Открытая командная консоль c: \> Java-версия
Linux Открытый командный терминал $ java-версия
макинтош Открытый терминал машина: ~ Джозеф $ Java-версия

Давайте проверим вывод для всех операционных систем —

Операционные системы Выход
Windows

Java-версия «1.6.0_21»

Java (TM) SE Runtime Environment (сборка 1.6.0_21-b11)

Java HotSpot (TM) 64-разрядная серверная виртуальная машина (сборка 23.21-b01, смешанный режим)

Linux

Java-версия «1.6.0_21»

Java (TM) SE Runtime Environment (сборка 1.6.0_21-b11)

Java HotSpot (TM) 64-разрядная серверная виртуальная машина (сборка 23.21-b01, смешанный режим)

макинтош

Java-версия «1.6.0_21»

Java (TM) SE Runtime Environment (сборка 1.6.0_21-b11)

Java HotSpot (TM) 64-разрядная серверная виртуальная машина (сборка 23.21-b01, смешанный режим)

Java-версия «1.6.0_21»

Java (TM) SE Runtime Environment (сборка 1.6.0_21-b11)

Java HotSpot (TM) 64-разрядная серверная виртуальная машина (сборка 23.21-b01, смешанный режим)

Java-версия «1.6.0_21»

Java (TM) SE Runtime Environment (сборка 1.6.0_21-b11)

Java HotSpot (TM) 64-разрядная серверная виртуальная машина (сборка 23.21-b01, смешанный режим)

Java-версия «1.6.0_21»

Java (TM) SE Runtime Environment (сборка 1.6.0_21-b11)

Java HotSpot (TM) 64-разрядная серверная виртуальная машина (сборка 23.21-b01, смешанный режим)

Если у вас не установлена ​​Java, установите Java Software Development Kit (SDK) с сайта www.oracle.com . Мы предполагаем, что Java 1.6.0_21 установлена ​​как версия для этого урока.

Шаг 2 — Установите JAVA Environment

Установите переменную среды JAVA_HOME, чтобы указать местоположение базовой директории, где установлена ​​Java в вашей системе. Например,

Операционные системы Выход
Windows Задайте для переменной среды JAVA_HOME значение C: \ Program Files \ Java \ jdk1.6.0_21.
Linux экспорт JAVA_HOME = / usr / local / java-current
макинтош export JAVA_HOME = / Библиотека / Java / Главная

Добавьте расположение компилятора Java в системный путь.

Операционные системы Выход
Windows Добавьте строку; C: \ Program Files \ Java \ jdk1.6.0_21 \ bin в конец системной переменной Path.
Linux экспорт PATH = $ PATH: $ JAVA_HOME / bin /
макинтош не требуется

Проверьте установку Java с помощью команды java -version, описанной выше.

Шаг 3. Загрузите и установите IDE NetBeans

Загрузите последнюю версию среды IDE NetBeans с netbeans.org . На момент написания этого руководства я скачал Netbeans 7.3, поставляемый в комплекте с JDK 1.7, по следующей ссылке www.oracle.com

Операционные системы Имя установщика
Windows Netbeans 7.3
Linux Netbeans 7.3
макинтош Netbeans 7.3

Шаг 4 — Настройка сервера приложений JBoss

Вы можете скачать последнюю версию JBoss Server с www.jboss.org . Загрузите архив согласно платформе. Распакуйте Jboss в любое место на вашем компьютере.

Операционные системы Имя файла
Windows jboss-5.1.0.GA-jdk6.zip
Linux JBoss-5.1.0.GA-src.tar.gz
макинтош JBoss-5.1.0.GA-src.tar.gz

Шаг 5. Настройка плагинов JEE для NetBeans

Откройте окно плагинов, используя Инструменты> Плагины. Откройте вкладку «Доступный плагин» и выберите «База Java EE» и «EJB и EAR» в категории «Java Web и EE». Нажмите кнопку установки. Netbeans загрузит и установит соответствующие плагины. Проверьте установку плагинов, используя вкладку «Установлено» (как показано на рисунке ниже).

Установленные плагины

Шаг 6 — Настройте сервер JBoss в NetBeans

Перейдите на вкладку «Службы» и щелкните правой кнопкой мыши серверы, чтобы добавить новый сервер.

Добавить сервер

Откроется мастер добавления экземпляра сервера. Выберите JBoss и на следующем шаге введите соответствующие данные для настройки сервера в NetBeans.

Выберите сервер

Как только все настроено, вы увидите следующий экран.

Установленные серверы

Шаг 7 — Установить сервер базы данных (PostGreSql)

Загрузите последнюю версию сервера базы данных PostGreSql с сайта www.postgresql.org . На момент написания этого урока я скачал PostGreSql 9.2

Операционные системы Имя установщика
Windows PostGreSql 9.2
Linux PostGreSql 9.2
макинтош PostGreSql 9.2

EJB — Создать приложение

Для создания простого модуля EJB мы будем использовать NetBeans, мастер «New project». В приведенном ниже примере мы создадим проект модуля EJB с именем Component.

Создать проект

В IDE NetBeans выберите « Файл»> «Новый проект»> . Вы увидите следующий экран

Мастер создания проекта, шаг 1

Выберите тип проекта в категории Java EE , Тип проекта в качестве модуля EJB . Нажмите кнопку Далее> . Вы увидите следующий экран.

Мастер создания проекта, шаг 2

Введите название проекта и местоположение. Нажмите кнопку Далее> . Вы увидите следующий экран.

Мастер создания проекта, шаг 3

Выберите Сервер в качестве Сервера приложений JBoss . Нажмите кнопку Готово . Вы увидите следующий проект, созданный NetBeans.

Исследователь проекта

Создать образец EJB

Для создания простого EJB мы будем использовать мастер «New» NetBeans. В приведенном ниже примере мы создадим EJB-класс без сохранения состояния с именем librarySessionBean в рамках проекта EjbComponent.

Выберите проект EjbComponent в окне проводника проекта и щелкните по нему правой кнопкой мыши. Выберите, New> Session Bean . Вы увидите мастера New Session Bean .

Мастер новых сессий

Введите имя сессионного компонента и имя пакета. Нажмите кнопку Готово . Вы увидите следующие классы EJB, созданные NetBeans.

  • LibrarySessionBean — сессионный компонент без сохранения состояния

  • LibrarySessionBeanLocal — локальный интерфейс для сессионного компонента

LibrarySessionBean — сессионный компонент без сохранения состояния

LibrarySessionBeanLocal — локальный интерфейс для сессионного компонента

Я меняю локальный интерфейс на удаленный, так как мы собираемся получить доступ к нашему EJB в консольном приложении. Удаленный / локальный интерфейс используется для представления бизнес-методов, которые должен реализовать EJB.

LibrarySessionBeanLocal переименовывается в LibrarySessionBeanRemote, а LibrarySessionBean реализует интерфейс 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;
   }
}

Построить проект

  • Выберите проект EjbComponent в окне Project Explorer.
  • Щелкните правой кнопкой мыши, чтобы открыть контекстное меню.
  • Выберите очистить и построить.

Вы увидите следующий вывод в выводе консоли 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)

Запустите сервер приложений

  • Выберите сервер приложений JBoss в разделе «Серверы» в окне «Службы».
  • Щелкните правой кнопкой мыши, чтобы открыть контекстное меню.
  • Выберите начало.

Вы увидите следующий вывод в NetBeans, вывод в разделе Сервер приложений JBoss.

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

Развернуть проект

  • Выберите проект EjbComponent в окне Project Explorer.
  • Щелкните правой кнопкой мыши, чтобы открыть контекстное меню.
  • Выберите Deploy.

Вы увидите следующий вывод в выводе консоли 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)

Вывод журнала сервера приложений 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

Создать клиент для доступа к EJB

  • В IDE NetBeans выберите « Файл»> «Новый проект»> .

  • Выберите тип проекта в категории Java , Тип проекта в качестве Java-приложения . Нажмите кнопку Далее>

  • Введите название проекта и местоположение. Нажмите Готово> кнопка. Мы выбрали имя как EjbTester.

  • Щелкните правой кнопкой мыши на имени проекта в окне Project Explorer. Выберите свойства .

  • Добавьте проект компонента EJB, созданный ранее в библиотеках, используя кнопку « Добавить проект» на вкладке « Компиляция ».

  • Добавьте библиотеки jboss с помощью кнопки « Добавить jar / folder» на вкладке «Компиляция». Библиотеки Jboss могут быть расположены в <папке установки jboss >> в папке клиента.

В IDE NetBeans выберите « Файл»> «Новый проект»> .

Выберите тип проекта в категории Java , Тип проекта в качестве Java-приложения . Нажмите кнопку Далее>

Введите название проекта и местоположение. Нажмите Готово> кнопка. Мы выбрали имя как EjbTester.

Щелкните правой кнопкой мыши на имени проекта в окне Project Explorer. Выберите свойства .

Добавьте проект компонента EJB, созданный ранее в библиотеках, используя кнопку « Добавить проект» на вкладке « Компиляция ».

Добавьте библиотеки jboss с помощью кнопки « Добавить jar / folder» на вкладке «Компиляция». Библиотеки Jboss могут быть расположены в <папке установки jboss >> в папке клиента.

Создайте jndi.properties под проектом, скажем, 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

Создайте пакет com.tutorialspoint.test и класс EJBTester.java под ним.

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

Запустите клиент для доступа к EJB

Найдите EJBTester.java в проводнике проекта. Щелкните правой кнопкой мыши класс EJBTester и выберите файл запуска .

Проверьте следующий вывод в консоли 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)

В следующих главах мы рассмотрим несколько аспектов этого полного EJB-приложения.

EJB — бин без гражданства

Сессионный компонент без сохранения состояния — это тип корпоративного компонента, который обычно используется для выполнения независимых операций. Сессионный компонент без сохранения состояния согласно его имени не имеет никакого связанного состояния клиента, но он может сохранить свое состояние экземпляра. Контейнер EJB обычно создает пул из нескольких объектов bean-объектов без сохранения состояния и использует эти объекты для обработки запроса клиента. Из-за пула значения переменных экземпляров не гарантируются одинаковыми при поиске / вызове метода.

Шаги по созданию EJB без сохранения состояния

Ниже приведены шаги, необходимые для создания EJB без сохранения состояния.

  • Создайте удаленный / локальный интерфейс, раскрывающий бизнес-методы.

  • Этот интерфейс будет использоваться клиентским приложением EJB.

  • Используйте аннотацию @Local, если клиент EJB находится в той же среде, где должен быть развернут сессионный компонент EJB.

  • Используйте аннотацию @Remote, если клиент EJB находится в другой среде, в которой должен быть развернут сессионный компонент EJB.

  • Создайте сессионный компонент без сохранения состояния, реализуя описанный выше интерфейс.

  • Используйте аннотацию @Stateless, чтобы обозначить ее как компонент без состояния. Контейнер EJB автоматически создает соответствующие конфигурации или интерфейсы, необходимые для чтения этой аннотации во время развертывания.

Создайте удаленный / локальный интерфейс, раскрывающий бизнес-методы.

Этот интерфейс будет использоваться клиентским приложением EJB.

Используйте аннотацию @Local, если клиент EJB находится в той же среде, где должен быть развернут сессионный компонент EJB.

Используйте аннотацию @Remote, если клиент EJB находится в другой среде, в которой должен быть развернут сессионный компонент EJB.

Создайте сессионный компонент без сохранения состояния, реализуя описанный выше интерфейс.

Используйте аннотацию @Stateless, чтобы обозначить ее как компонент без состояния. Контейнер EJB автоматически создает соответствующие конфигурации или интерфейсы, необходимые для чтения этой аннотации во время развертывания.

Удаленный интерфейс

import javax.ejb.Remote;
 
@Remote
public interface LibrarySessionBeanRemote {
   //add business method declarations
}

EJB без гражданства

@Stateless
public class LibrarySessionBean implements LibrarySessionBeanRemote {
   //implement business method 
}

Пример приложения

Давайте создадим тестовое EJB-приложение для тестирования EJB без сохранения состояния.

шаг Описание
1

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.stateless, как описано в главе EJB — Создание приложения . Вы также можете использовать проект, созданный в главе EJB — Создание приложения как таковой, для понимания концепций EJB без сохранения состояния.

2

Создайте LibrarySessionBean.java и LibrarySessionBeanRemote, как описано в главе EJB — Создание приложения . Сохраните остальные файлы без изменений.

3

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

4

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

5

Теперь создайте EJB-клиент, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» .

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.stateless, как описано в главе EJB — Создание приложения . Вы также можете использовать проект, созданный в главе EJB — Создание приложения как таковой, для понимания концепций EJB без сохранения состояния.

Создайте LibrarySessionBean.java и LibrarySessionBeanRemote, как описано в главе EJB — Создание приложения . Сохраните остальные файлы без изменений.

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

Теперь создайте EJB-клиент, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» .

EJBComponent (модуль 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;
   }
}
  • Как только вы развернете проект EjbComponent в JBOSS, обратите внимание на журнал jboss.

  • JBoss автоматически создал запись JNDI для нашего сессионного компонента — LibrarySessionBean / remote .

  • Мы будем использовать эту строку поиска для получения удаленного бизнес-объекта типа — com.tutorialspoint.stateless.LibrarySessionBeanRemote

Как только вы развернете проект EjbComponent в JBOSS, обратите внимание на журнал jboss.

JBoss автоматически создал запись JNDI для нашего сессионного компонента — LibrarySessionBean / remote .

Мы будем использовать эту строку поиска для получения удаленного бизнес-объекта типа — com.tutorialspoint.stateless.LibrarySessionBeanRemote

Вывод журнала сервера приложений 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 (клиент 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
  • Эти свойства используются для инициализации объекта InitialContext сервиса именования java.

  • Объект InitialContext будет использоваться для поиска сессионного компонента без сохранения состояния.

Эти свойства используются для инициализации объекта InitialContext сервиса именования java.

Объект InitialContext будет использоваться для поиска сессионного компонента без сохранения состояния.

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 выполняет следующие задачи —

  • Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

  • В методе testStatelessEjb () поиск jndi выполняется с именем — «LibrarySessionBean / remote» для получения удаленного бизнес-объекта (ejb без сохранения состояния).

  • Затем пользователю показывается пользовательский интерфейс магазина библиотеки, и ему / ей предлагается ввести выбор.

  • Если пользователь вводит 1, система запрашивает имя книги и сохраняет книгу, используя метод addBook () сессионного компонента без сохранения состояния. Сессионный компонент хранит книгу в своей переменной экземпляра.

  • Если пользователь вводит 2, система получает книги, используя метод getBooks () сессионного компонента без сохранения состояния, и завершает работу.

  • Затем выполняется другой поиск jndi с именем — «LibrarySessionBean / remote» для повторного получения удаленного бизнес-объекта (EJB без сохранения состояния) и составления списка книг.

Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

В методе testStatelessEjb () поиск jndi выполняется с именем — «LibrarySessionBean / remote» для получения удаленного бизнес-объекта (ejb без сохранения состояния).

Затем пользователю показывается пользовательский интерфейс магазина библиотеки, и ему / ей предлагается ввести выбор.

Если пользователь вводит 1, система запрашивает имя книги и сохраняет книгу, используя метод addBook () сессионного компонента без сохранения состояния. Сессионный компонент хранит книгу в своей переменной экземпляра.

Если пользователь вводит 2, система получает книги, используя метод getBooks () сессионного компонента без сохранения состояния, и завершает работу.

Затем выполняется другой поиск jndi с именем — «LibrarySessionBean / remote» для повторного получения удаленного бизнес-объекта (EJB без сохранения состояния) и составления списка книг.

Запустите клиент для доступа к EJB

Найдите EJBTester.java в проводнике проекта. Щелкните правой кнопкой мыши класс EJBTester и выберите файл запуска .

Проверьте следующий вывод в консоли 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)

Снова запустите клиент для доступа к EJB

Найдите EJBTester.java в проводнике проекта. Щелкните правой кнопкой мыши класс EJBTester и выберите файл запуска .

Проверьте следующий вывод в консоли 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)
  • Вывод, показанный выше, может варьироваться в зависимости от того, сколько объектов EJB без состояния поддерживает JBoss.

  • В случае, если поддерживается один объект EJB без сохранения состояния, вы можете увидеть один и тот же список книг после каждого поиска.

  • Контейнер EJB может возвращать один и тот же объект EJB без сохранения состояния для каждого поиска.

  • EJB-компонент без сохранения состояния сохраняет значение переменной экземпляра до тех пор, пока сервер не будет перезапущен.

Вывод, показанный выше, может варьироваться в зависимости от того, сколько объектов EJB без состояния поддерживает JBoss.

В случае, если поддерживается один объект EJB без сохранения состояния, вы можете увидеть один и тот же список книг после каждого поиска.

Контейнер EJB может возвращать один и тот же объект EJB без сохранения состояния для каждого поиска.

EJB-компонент без сохранения состояния сохраняет значение переменной экземпляра до тех пор, пока сервер не будет перезапущен.

EJB — Stateful Bean

Сессионный компонент с состоянием — это тип корпоративного компонента, который сохраняет диалоговое состояние с клиентом. Сессионный компонент с сохранением состояния согласно своему имени сохраняет связанное состояние клиента в своих переменных экземпляра. Контейнер EJB создает отдельный сессионный компонент с сохранением состояния для обработки каждого запроса клиента. Как только закончится область запроса, сессионный компонент с сохранением состояния уничтожается.

Шаги для создания Stateful EJB

Ниже приведены шаги, необходимые для создания EJB с состоянием:

  • Создайте удаленный / локальный интерфейс, раскрывающий бизнес-методы.

  • Этот интерфейс будет использоваться клиентским приложением EJB.

  • Используйте аннотацию @Local, если клиент EJB находится в той же среде, где необходимо развернуть сессионный компонент EJB.

  • Используйте аннотацию @Remote, если клиент EJB находится в другой среде, где требуется развернуть сессионный компонент EJB.

  • Создайте сессионный компонент с сохранением состояния, реализуя вышеуказанный интерфейс.

  • Используйте аннотацию @Stateful, чтобы обозначить ее как компонент с состоянием. Контейнер EJB автоматически создает соответствующие конфигурации или интерфейсы, необходимые для чтения этой аннотации во время развертывания.

Создайте удаленный / локальный интерфейс, раскрывающий бизнес-методы.

Этот интерфейс будет использоваться клиентским приложением EJB.

Используйте аннотацию @Local, если клиент EJB находится в той же среде, где необходимо развернуть сессионный компонент EJB.

Используйте аннотацию @Remote, если клиент EJB находится в другой среде, где требуется развернуть сессионный компонент EJB.

Создайте сессионный компонент с сохранением состояния, реализуя вышеуказанный интерфейс.

Используйте аннотацию @Stateful, чтобы обозначить ее как компонент с состоянием. Контейнер EJB автоматически создает соответствующие конфигурации или интерфейсы, необходимые для чтения этой аннотации во время развертывания.

Удаленный интерфейс

import javax.ejb.Remote;
 
@Remote
public interface LibraryStatefulSessionBeanRemote {
   //add business method declarations
}

Stateful EJB

@Stateful
public class LibraryStatefulSessionBean implements LibraryStatefulSessionBeanRemote {
   //implement business method 
}

Пример приложения

Давайте создадим тестовое EJB-приложение для тестирования EJB с отслеживанием состояния.

шаг Описание
1

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.stateful, как описано в главе EJB — Создание приложения . Вы также можете использовать проект, созданный в главе EJB — Создание приложения как таковой, для понимания концепций EJB с состоянием.

2

Создайте LibraryStatefulSessionBean.java и LibraryStatefulSessionBeanRemote, как описано в главе EJB — Создание приложения . Сохраните остальные файлы без изменений.

3

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

4

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

5

Теперь создайте EJB-клиент, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» .

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.stateful, как описано в главе EJB — Создание приложения . Вы также можете использовать проект, созданный в главе EJB — Создание приложения как таковой, для понимания концепций EJB с состоянием.

Создайте LibraryStatefulSessionBean.java и LibraryStatefulSessionBeanRemote, как описано в главе EJB — Создание приложения . Сохраните остальные файлы без изменений.

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

Теперь создайте EJB-клиент, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» .

EJBComponent (модуль 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;
   }
}
  • Как только вы развернете проект EjbComponent в JBOSS, обратите внимание на журнал jboss.

  • JBoss автоматически создал запись JNDI для нашего сессионного компонента — LibraryStatefulSessionBean / remote .

  • Мы будем использовать эту строку поиска для получения удаленного бизнес-объекта типа — com.tutorialspoint.stateful.LibraryStatefulSessionBeanRemote

Как только вы развернете проект EjbComponent в JBOSS, обратите внимание на журнал jboss.

JBoss автоматически создал запись JNDI для нашего сессионного компонента — LibraryStatefulSessionBean / remote .

Мы будем использовать эту строку поиска для получения удаленного бизнес-объекта типа — com.tutorialspoint.stateful.LibraryStatefulSessionBeanRemote

Вывод журнала сервера приложений 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 (клиент 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
  • Эти свойства используются для инициализации объекта InitialContext сервиса именования java.

  • Объект InitialContext будет использоваться для поиска сессионного компонента с сохранением состояния.

Эти свойства используются для инициализации объекта InitialContext сервиса именования java.

Объект InitialContext будет использоваться для поиска сессионного компонента с сохранением состояния.

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 выполняет следующие задачи —

  • Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

  • В методе testStatefulEjb () поиск jndi выполняется с именем — «LibraryStatefulSessionBean / remote» для получения удаленного бизнес-объекта (stateful ejb).

  • Затем пользователю показывается пользовательский интерфейс хранилища библиотеки, и ему / ей предлагается ввести выбор.

  • Если пользователь вводит 1, система запрашивает имя книги и сохраняет книгу, используя метод addBook () сессионного компонента с состоянием. Сессионный компонент хранит книгу в своей переменной экземпляра.

  • Если пользователь вводит 2, система получает книги, используя метод getBooks () сессионного компонента с состоянием, и завершает работу.

  • Затем выполняется другой поиск jndi с именем — «LibraryStatefulSessionBean / remote», чтобы снова получить удаленный бизнес-объект (EJB с сохранением состояния) и составить список книг.

Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

В методе testStatefulEjb () поиск jndi выполняется с именем — «LibraryStatefulSessionBean / remote» для получения удаленного бизнес-объекта (stateful ejb).

Затем пользователю показывается пользовательский интерфейс хранилища библиотеки, и ему / ей предлагается ввести выбор.

Если пользователь вводит 1, система запрашивает имя книги и сохраняет книгу, используя метод addBook () сессионного компонента с состоянием. Сессионный компонент хранит книгу в своей переменной экземпляра.

Если пользователь вводит 2, система получает книги, используя метод getBooks () сессионного компонента с состоянием, и завершает работу.

Затем выполняется другой поиск jndi с именем — «LibraryStatefulSessionBean / remote», чтобы снова получить удаленный бизнес-объект (EJB с сохранением состояния) и составить список книг.

Запустите клиент для доступа к EJB

Найдите EJBTester.java в проводнике проекта. Щелкните правой кнопкой мыши класс EJBTester и выберите файл запуска .

Проверьте следующий вывод в консоли 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)

Снова запустите клиент для доступа к EJB

Найдите EJBTester.java в проводнике проекта. Щелкните правой кнопкой мыши класс EJBTester и выберите файл запуска .

Проверьте следующий вывод в консоли 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)
  • Вывод, показанный выше, гласит, что для каждого поиска возвращается отдельный экземпляр EJB с состоянием.

  • EJB-объект с состоянием сохраняет значение только для одного сеанса. Как и во втором запуске, мы не получаем никакой ценности книг.

Вывод, показанный выше, гласит, что для каждого поиска возвращается отдельный экземпляр EJB с состоянием.

EJB-объект с состоянием сохраняет значение только для одного сеанса. Как и во втором запуске, мы не получаем никакой ценности книг.

EJB — настойчивость

EJB 3.0, объектный компонент, используемый в EJB 2.0, в значительной степени заменен механизмом персистентности. Теперь объектный бин — это простой POJO, имеющий отображение с таблицей.

Ниже приведены ключевые действующие лица в постоянном API.

  • Entity — постоянный объект, представляющий запись хранилища данных. Хорошо быть сериализуемым.

  • EntityManager — Персистентный интерфейс для выполнения операций с данными, таких как добавление / удаление / обновление / поиск над постоянным объектом (сущностью). Это также помогает выполнять запросы, используя интерфейс запросов .

  • Модуль сохраняемости (persistence.xml) — модуль сохраняемости описывает свойства механизма сохранения.

  • Источник данных (* ds.xml) — Источник данных описывает свойства, связанные с хранилищем данных, такие как URL-адрес соединения. имя пользователя, пароль и т. д.

Entity — постоянный объект, представляющий запись хранилища данных. Хорошо быть сериализуемым.

EntityManager — Персистентный интерфейс для выполнения операций с данными, таких как добавление / удаление / обновление / поиск над постоянным объектом (сущностью). Это также помогает выполнять запросы, используя интерфейс запросов .

Модуль сохраняемости (persistence.xml) — модуль сохраняемости описывает свойства механизма сохранения.

Источник данных (* ds.xml) — Источник данных описывает свойства, связанные с хранилищем данных, такие как URL-адрес соединения. имя пользователя, пароль и т. д.

Чтобы продемонстрировать механизм персистентности EJB, нам нужно выполнить следующие задачи:

  • Шаг 1 — Создать таблицу в базе данных.

  • Шаг 2 — Создайте класс Entity, соответствующий таблице.

  • Шаг 3 — Создание источника данных и модуля персистентности.

  • Шаг 4 — Создайте EJB без состояния, имеющий экземпляр EntityManager.

  • Шаг 5 — Обновите EJB без сохранения состояния. Добавьте методы для добавления записей и получения записей из базы данных через менеджер сущностей.

  • Шаг 6 — Клиент консольного приложения получит доступ к EJB без сохранения состояния для сохранения данных в базе данных.

Шаг 1 — Создать таблицу в базе данных.

Шаг 2 — Создайте класс Entity, соответствующий таблице.

Шаг 3 — Создание источника данных и модуля персистентности.

Шаг 4 — Создайте EJB без состояния, имеющий экземпляр EntityManager.

Шаг 5 — Обновите EJB без сохранения состояния. Добавьте методы для добавления записей и получения записей из базы данных через менеджер сущностей.

Шаг 6 — Клиент консольного приложения получит доступ к EJB без сохранения состояния для сохранения данных в базе данных.

Создать таблицу

Создать таблицу книг по умолчанию в базе данных postgres .

CREATE TABLE books (
   id     integer PRIMARY KEY,
   name   varchar(50)
);

Создать класс сущности

//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;
   }
   ...
}

Создать источник данных и блок персистентности

Источник данных (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>

Персистентный блок (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>

Создайте EJB без состояния, имеющий экземпляр 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();
   }
   ...
}

После создания модуля EJB нам нужен клиент для доступа к bean-компоненту без сохранения состояния, который мы собираемся создать в следующем разделе.

Пример приложения

Давайте создадим тестовое EJB-приложение для тестирования механизма персистентности EJB.

шаг Описание
1

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.entity, как описано в главе EJB — Создание приложения . Вы также можете использовать проект, созданный в главе EJB — Создание приложения как таковой, для понимания концепций персистентности EJB.

2

Создайте Book.java в пакете com.tutorialspoint.entity и измените его, как показано ниже.

3

Создайте LibraryPersistentBean.java и LibraryPersistentBeanRemote, как описано в главах EJB — Создание приложения, и измените их, как показано ниже.

4

Создайте jboss-ds.xml в EjbComponent> установочной папке и persistence.xml в EjbComponent> src> conf . Эти папки можно увидеть на вкладке файлов в Netbeans. Измените эти файлы, как показано выше.

5

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

6

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

7

Теперь создайте EJB-клиент, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» . Измените его, как показано ниже.

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.entity, как описано в главе EJB — Создание приложения . Вы также можете использовать проект, созданный в главе EJB — Создание приложения как таковой, для понимания концепций персистентности EJB.

Создайте Book.java в пакете com.tutorialspoint.entity и измените его, как показано ниже.

Создайте LibraryPersistentBean.java и LibraryPersistentBeanRemote, как описано в главах EJB — Создание приложения, и измените их, как показано ниже.

Создайте jboss-ds.xml в EjbComponent> установочной папке и persistence.xml в EjbComponent> src> conf . Эти папки можно увидеть на вкладке файлов в Netbeans. Измените эти файлы, как показано выше.

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

Теперь создайте EJB-клиент, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» . Измените его, как показано ниже.

EJBComponent (модуль 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();
   }
}
  • Как только вы развернете проект EjbComponent в JBOSS, обратите внимание на журнал jboss.

  • JBoss автоматически создал запись JNDI для нашего сессионного компонента — LibraryPersistentBean / remote .

  • Мы будем использовать эту строку поиска для получения удаленного бизнес-объекта типа — com.tutorialspoint.stateless.LibraryPersistentBeanRemote

Как только вы развернете проект EjbComponent в JBOSS, обратите внимание на журнал jboss.

JBoss автоматически создал запись JNDI для нашего сессионного компонента — LibraryPersistentBean / remote .

Мы будем использовать эту строку поиска для получения удаленного бизнес-объекта типа — com.tutorialspoint.stateless.LibraryPersistentBeanRemote

Вывод журнала сервера приложений 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 (клиент 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
  • Эти свойства используются для инициализации объекта InitialContext сервиса именования java.

  • Объект InitialContext будет использоваться для поиска сессионного компонента без сохранения состояния.

Эти свойства используются для инициализации объекта InitialContext сервиса именования java.

Объект InitialContext будет использоваться для поиска сессионного компонента без сохранения состояния.

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 выполняет следующие задачи.

  • Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

  • В методе testStatefulEjb () поиск jndi выполняется с именем — «LibraryStatefulSessionBean / remote» для получения удаленного бизнес-объекта (stateful ejb).

  • Затем пользователю показывается пользовательский интерфейс магазина библиотеки, и ему / ей предлагается ввести выбор.

  • Если пользователь вводит 1, система запрашивает имя книги и сохраняет книгу, используя метод addBook () сессионного компонента без сохранения состояния. Сессионный компонент сохраняет книгу в базе данных с помощью вызова EntityManager.

  • Если пользователь вводит 2, система получает книги, используя метод getBooks () сессионного компонента с состоянием, и завершает работу.

  • Затем выполняется другой поиск jndi с именем — «LibraryStatelessSessionBean / remote» для повторного получения удаленного бизнес-объекта (EJB без сохранения состояния) и составления списка книг.

Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

В методе testStatefulEjb () поиск jndi выполняется с именем — «LibraryStatefulSessionBean / remote» для получения удаленного бизнес-объекта (stateful ejb).

Затем пользователю показывается пользовательский интерфейс магазина библиотеки, и ему / ей предлагается ввести выбор.

Если пользователь вводит 1, система запрашивает имя книги и сохраняет книгу, используя метод addBook () сессионного компонента без сохранения состояния. Сессионный компонент сохраняет книгу в базе данных с помощью вызова EntityManager.

Если пользователь вводит 2, система получает книги, используя метод getBooks () сессионного компонента с состоянием, и завершает работу.

Затем выполняется другой поиск jndi с именем — «LibraryStatelessSessionBean / remote» для повторного получения удаленного бизнес-объекта (EJB без сохранения состояния) и составления списка книг.

Запустите клиент для доступа к EJB

Найдите EJBTester.java в проводнике проекта. Щелкните правой кнопкой мыши класс EJBTester и выберите файл запуска .

Проверьте следующий вывод в консоли 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

Перезапустите JBoss, прежде чем получить доступ к EJB.

Найдите EJBTester.java в проводнике проекта. Щелкните правой кнопкой мыши класс EJBTester и выберите файл запуска .

Проверьте следующий вывод в консоли 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)

Вывод, показанный выше, гласит, что книги хранятся в постоянном хранилище и извлекаются из базы данных.

EJB — бобы, управляемые сообщениями

Управляемый сообщениями компонент — это тип корпоративного компонента, который вызывается контейнером EJB при получении сообщения из очереди или темы. Компонент, управляемый сообщениями, является компонентом без сохранения состояния и используется для асинхронного выполнения задачи.

Чтобы продемонстрировать использование bean-объекта, управляемого сообщениями, мы будем использовать главу EJB-persistence, и нам нужно выполнить следующие задачи:

  • Шаг 1 — Создать таблицу в базе данных (см. Главу EJB-Persistence ).

  • Шаг 2 — Создайте класс Entity, соответствующий таблице (см. Главу EJB-Persistence ).

  • Шаг 3 — Создание источника данных и модуля постоянства (см. Главу EJB-Постоянство ).

  • Шаг 4 — Создайте EJB без сохранения состояния с экземпляром EntityManager (см. Главу EJB-Persistence ).

  • Шаг 5 — Обновите ejb без сохранения состояния. Добавьте методы, чтобы добавлять записи и получать записи из базы данных через менеджер сущностей (см. Главу EJB-Persistence ).

  • Шаг 6 — Создайте очередь с именем BookQueue в каталоге приложения JBoss по умолчанию .

  • Шаг 7 — Клиент консольного приложения отправит сообщение в эту очередь.

  • Шаг 8 — Создайте компонент, управляемый сообщениями, который будет использовать компонент без сохранения состояния для сохранения данных клиента.

  • Шаг 9 — EJB-контейнер jboss вызовет указанный выше управляемый компонентом bean и передаст ему сообщение, на которое клиент будет отправлять.

Шаг 1 — Создать таблицу в базе данных (см. Главу EJB-Persistence ).

Шаг 2 — Создайте класс Entity, соответствующий таблице (см. Главу EJB-Persistence ).

Шаг 3 — Создание источника данных и модуля постоянства (см. Главу EJB-Постоянство ).

Шаг 4 — Создайте EJB без сохранения состояния с экземпляром EntityManager (см. Главу EJB-Persistence ).

Шаг 5 — Обновите ejb без сохранения состояния. Добавьте методы, чтобы добавлять записи и получать записи из базы данных через менеджер сущностей (см. Главу EJB-Persistence ).

Шаг 6 — Создайте очередь с именем BookQueue в каталоге приложения JBoss по умолчанию .

Шаг 7 — Клиент консольного приложения отправит сообщение в эту очередь.

Шаг 8 — Создайте компонент, управляемый сообщениями, который будет использовать компонент без сохранения состояния для сохранения данных клиента.

Шаг 9 — EJB-контейнер jboss вызовет указанный выше управляемый компонентом bean и передаст ему сообщение, на которое клиент будет отправлять.

Создать очередь

Создайте файл с именем jbossmq-destination-service.xml, если он не существует в <Папке установки JBoss>> сервер> default> папка развертывания .

Здесь мы создаем очередь с именем BookQueue —

JBossMQ-направления-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>  

Когда вы запустите JBoss, вы увидите похожую запись в журнале jboss.

...
10:37:06,167 INFO  [QueueService] Queue[/queue/BookQueue] started, fullSize=200000, pageSize=2000, downCacheSize=2000
...

Создать сообщение управляемый компонент

@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 помечен аннотацией @MessageDriven, чтобы пометить его как компонент, управляемый сообщениями.

  • Его свойства определены как destinationType — Queue и destination — / queue / BookQueue.

  • Он реализует интерфейс MessageListener, который предоставляет метод onMessage.

  • Он имеет MessgeDrivenContext в качестве ресурса.

  • Компонент LibraryPersistentBeanRemote без сохранения состояния внедряется в этот компонент для сохранения.

LibraryMessageBean помечен аннотацией @MessageDriven, чтобы пометить его как компонент, управляемый сообщениями.

Его свойства определены как destinationType — Queue и destination — / queue / BookQueue.

Он реализует интерфейс MessageListener, который предоставляет метод onMessage.

Он имеет MessgeDrivenContext в качестве ресурса.

Компонент LibraryPersistentBeanRemote без сохранения состояния внедряется в этот компонент для сохранения.

Создайте проект EjbComponent и разверните его на JBoss. После сборки и развертывания модуля EJB нам нужен клиент для отправки сообщения в очередь jboss.

Пример приложения

Давайте создадим тестовое EJB-приложение для тестирования Message Driven Bean.

шаг Описание
1

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.entity, как описано в главе EJB — Создание приложения . Вы также можете использовать проект, созданный в главе EJB — Создание приложения как таковой, для понимания концепций персистентности EJB.

2

Создайте Book.java в пакете com.tutorialspoint.entity, как он был создан в главе EJB-Persistence .

3

Создайте LibraryPersistentBean.java и LibraryPersistentBeanRemote, как они были созданы в главе EJB-Persistence .

4

Создайте jboss-ds.xml в EjbComponent> установочной папке и persistence.xml в EjbComponent> src> conf . Эти папки можно увидеть на вкладке файлов в Netbeans, как они созданы в главе EJB-Persistence .

5

Создайте LibraryMessageBean.java в пакете com.tutorialspoint.messagebean и измените его, как показано ниже.

6

Создайте очередь BookQueue в Jboss, как описано выше.

7

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

8

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

9

Теперь создайте EJB-клиент, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» . Измените его, как показано ниже.

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.entity, как описано в главе EJB — Создание приложения . Вы также можете использовать проект, созданный в главе EJB — Создание приложения как таковой, для понимания концепций персистентности EJB.

Создайте Book.java в пакете com.tutorialspoint.entity, как он был создан в главе EJB-Persistence .

Создайте LibraryPersistentBean.java и LibraryPersistentBeanRemote, как они были созданы в главе EJB-Persistence .

Создайте jboss-ds.xml в EjbComponent> установочной папке и persistence.xml в EjbComponent> src> conf . Эти папки можно увидеть на вкладке файлов в Netbeans, как они созданы в главе EJB-Persistence .

Создайте LibraryMessageBean.java в пакете com.tutorialspoint.messagebean и измените его, как показано ниже.

Создайте очередь BookQueue в Jboss, как описано выше.

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

Теперь создайте EJB-клиент, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» . Измените его, как показано ниже.

EJBComponent (модуль 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 (клиент 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 выполняет следующие задачи —

  • Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

  • В методе testStatefulEjb () поиск jndi выполняется с именем — «/ queue / BookQueue», чтобы получить разрешение очереди, доступной в Jboss. Затем отправитель создается с использованием сеанса очереди.

  • Затем пользователю показывается пользовательский интерфейс магазина библиотеки, и ему / ей предлагается ввести выбор.

  • Если пользователь вводит 1, система запрашивает имя книги, а отправитель отправляет имя книги в очередь. Когда контейнер JBoss получает это сообщение в очереди, он вызывает метод onMessage нашего бина, управляемого сообщениями. Наш компонент, управляемый сообщениями, затем сохраняет книгу, используя метод addBook () сессионного компонента с сохранением состояния. Сессионный компонент сохраняет книгу в базе данных с помощью вызова EntityManager.

  • Если пользователь вводит 2, тогда выполняется другой поиск jndi с именем — «LibraryStatefulSessionBean / remote», чтобы снова получить удаленный бизнес-объект (EJB с сохранением состояния) и выполнить распечатку книг.

Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

В методе testStatefulEjb () поиск jndi выполняется с именем — «/ queue / BookQueue», чтобы получить разрешение очереди, доступной в Jboss. Затем отправитель создается с использованием сеанса очереди.

Затем пользователю показывается пользовательский интерфейс магазина библиотеки, и ему / ей предлагается ввести выбор.

Если пользователь вводит 1, система запрашивает имя книги, а отправитель отправляет имя книги в очередь. Когда контейнер JBoss получает это сообщение в очереди, он вызывает метод onMessage нашего бина, управляемого сообщениями. Наш компонент, управляемый сообщениями, затем сохраняет книгу, используя метод addBook () сессионного компонента с сохранением состояния. Сессионный компонент сохраняет книгу в базе данных с помощью вызова EntityManager.

Если пользователь вводит 2, тогда выполняется другой поиск jndi с именем — «LibraryStatefulSessionBean / remote», чтобы снова получить удаленный бизнес-объект (EJB с сохранением состояния) и выполнить распечатку книг.

Запустите клиент для доступа к EJB

Найдите EJBTester.java в проводнике проекта. Щелкните правой кнопкой мыши класс EJBTester и выберите файл запуска .

Проверьте следующий вывод в консоли 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)

Вывод, показанный выше, говорит о том, что управляемый сообщениями bean-компонент получает сообщение и сохраняет книгу в постоянном хранилище, а книги извлекаются из базы данных.

EJB — Аннотации

Аннотации были введены в Java 5.0. Целью создания аннотаций является добавление дополнительной информации в класс или метаданных класса в его исходном коде. В EJB 3.0 аннотации используются для описания метаданных конфигурации в классах EJB. Таким образом, EJB 3.0 устраняет необходимость описания данных конфигурации в файлах конфигурации XML.

Контейнер EJB использует инструмент компилятора для генерации необходимых артефактов, таких как интерфейсы, дескрипторы развертывания, читая эти аннотации. Ниже приведен список часто используемых аннотаций.

Sr.no название Описание
1

javax.ejb.Stateless

Указывает, что данный класс EJB является сессионным компонентом без сохранения состояния.

Атрибуты

  • name — Используется для указания имени сессионного компонента.

  • mappedName — используется для указания имени JNDI сессионного компонента.

  • description — Используется для предоставления описания сессионного компонента.

2

javax.ejb.Stateful

Указывает, что данный класс EJB является сессионным компонентом с состоянием.

Атрибуты

  • name — Используется для указания имени сессионного компонента.

  • mappedName — используется для указания имени JNDI сессионного компонента.

  • description — Используется для предоставления описания сессионного компонента.

3

javax.ejb.MessageDrivenBean

Указывает, что данный класс EJB является компонентом, управляемым сообщениями.

Атрибуты

  • name — Используется для указания имени бина, управляемого сообщениями.

  • messageListenerInterface — Используется для указания интерфейса прослушивателя сообщений для бина, управляемого сообщениями.

  • ActivationConfig — используется для указания деталей конфигурации bean-объекта, управляемого сообщениями, в операционной среде bean-компонента, управляемого сообщениями.

  • mappedName — используется для указания имени JNDI сессионного компонента.

  • description — Используется для предоставления описания сессионного компонента.

4

javax.ejb.EJB

Используется для указания или внедрения зависимости как экземпляра EJB в другой EJB.

Атрибуты

  • name — Используется для указания имени, которое будет использоваться для поиска ссылочного компонента в среде.

  • beanInterface — используется для указания типа интерфейса ссылочного компонента.

  • beanName — Используется для предоставления имени ссылочного компонента.

  • mappedName — используется для указания имени JNDI ссылочного компонента.

  • description — Используется для предоставления описания ссылочного компонента.

5

javax.ejb.Local

Используется для указания локального интерфейса (ов) сессионного компонента. Этот локальный интерфейс сообщает бизнес-методы сессионного компонента (которые могут быть без сохранения состояния или с состоянием).

Этот интерфейс используется для предоставления бизнес-методов локальным клиентам, которые работают в том же развертывании / приложении, что и EJB.

Атрибуты

  • значение — используется для указания списка локальных интерфейсов в виде массива интерфейсов.

6

javax.ejb.Remote

Используется для указания удаленного интерфейса (ов) сессионного компонента. Этот удаленный интерфейс сообщает бизнес-методы сессионного компонента (которые могут быть без сохранения состояния или с сохранением состояния).

Этот интерфейс используется для предоставления бизнес-методов удаленным клиентам, которые работают в другом развертывании / приложении, как EJB.

Атрибуты

  • значение — используется для указания списка удаленных интерфейсов в виде массива интерфейсов.

7

javax.ejb. Активация ConfigProperty

Используется для указания свойств, необходимых для бина, управляемого сообщениями. Например, конечная точка, пункт назначения, селектор сообщений и т. Д.

Эта аннотация передается в качестве параметра для атрибута ActivationConfig аннотации javax.ejb.MessageDrivenBean.

Атрибуты

  • propertyName — название объекта.

  • propertyValue — стоимость имущества.

8

javax.ejb.PostActivate

Используется для указания метода обратного вызова жизненного цикла EJB. Этот метод будет вызван, когда EJB-контейнер только что активировал / повторно активировал экземпляр компонента.

Этот интерфейс используется для предоставления бизнес-методов локальным клиентам, которые работают в том же развертывании / приложении, что и EJB.

javax.ejb.Stateless

Указывает, что данный класс EJB является сессионным компонентом без сохранения состояния.

Атрибуты

name — Используется для указания имени сессионного компонента.

mappedName — используется для указания имени JNDI сессионного компонента.

description — Используется для предоставления описания сессионного компонента.

javax.ejb.Stateful

Указывает, что данный класс EJB является сессионным компонентом с состоянием.

Атрибуты

name — Используется для указания имени сессионного компонента.

mappedName — используется для указания имени JNDI сессионного компонента.

description — Используется для предоставления описания сессионного компонента.

javax.ejb.MessageDrivenBean

Указывает, что данный класс EJB является компонентом, управляемым сообщениями.

Атрибуты

name — Используется для указания имени бина, управляемого сообщениями.

messageListenerInterface — Используется для указания интерфейса прослушивателя сообщений для бина, управляемого сообщениями.

ActivationConfig — используется для указания деталей конфигурации bean-объекта, управляемого сообщениями, в операционной среде bean-компонента, управляемого сообщениями.

mappedName — используется для указания имени JNDI сессионного компонента.

description — Используется для предоставления описания сессионного компонента.

javax.ejb.EJB

Используется для указания или внедрения зависимости как экземпляра EJB в другой EJB.

Атрибуты

name — Используется для указания имени, которое будет использоваться для поиска ссылочного компонента в среде.

beanInterface — используется для указания типа интерфейса ссылочного компонента.

beanName — Используется для предоставления имени ссылочного компонента.

mappedName — используется для указания имени JNDI ссылочного компонента.

description — Используется для предоставления описания ссылочного компонента.

javax.ejb.Local

Используется для указания локального интерфейса (ов) сессионного компонента. Этот локальный интерфейс сообщает бизнес-методы сессионного компонента (которые могут быть без сохранения состояния или с состоянием).

Этот интерфейс используется для предоставления бизнес-методов локальным клиентам, которые работают в том же развертывании / приложении, что и EJB.

Атрибуты

значение — используется для указания списка локальных интерфейсов в виде массива интерфейсов.

javax.ejb.Remote

Используется для указания удаленного интерфейса (ов) сессионного компонента. Этот удаленный интерфейс сообщает бизнес-методы сессионного компонента (которые могут быть без сохранения состояния или с сохранением состояния).

Этот интерфейс используется для предоставления бизнес-методов удаленным клиентам, которые работают в другом развертывании / приложении, как EJB.

Атрибуты

значение — используется для указания списка удаленных интерфейсов в виде массива интерфейсов.

javax.ejb. Активация ConfigProperty

Используется для указания свойств, необходимых для бина, управляемого сообщениями. Например, конечная точка, пункт назначения, селектор сообщений и т. Д.

Эта аннотация передается в качестве параметра для атрибута ActivationConfig аннотации javax.ejb.MessageDrivenBean.

Атрибуты

propertyName — название объекта.

propertyValue — стоимость имущества.

javax.ejb.PostActivate

Используется для указания метода обратного вызова жизненного цикла EJB. Этот метод будет вызван, когда EJB-контейнер только что активировал / повторно активировал экземпляр компонента.

Этот интерфейс используется для предоставления бизнес-методов локальным клиентам, которые работают в том же развертывании / приложении, что и EJB.

EJB — обратные вызовы

Обратный вызов — это механизм, с помощью которого жизненный цикл корпоративного компонента может быть перехвачен. В спецификации EJB 3.0 указаны обратные вызовы, для которых создаются методы обработчика обратных вызовов. EJB Container вызывает эти обратные вызовы. Мы можем определить методы обратного вызова в самом классе EJB или в отдельном классе. EJB 3.0 предоставил много аннотаций для обратных вызовов.

Ниже приведен список аннотаций обратного вызова для bean-компонента без сохранения состояния.

аннотирование Описание
@PostConstruct Вызывается, когда бин создается впервые.
@PreDestroy Вызывается, когда бин удаляется из пула бинов или уничтожается.

Ниже приведен список аннотаций обратного вызова для компонента с состоянием —

аннотирование Описание
@PostConstruct Вызывается, когда бин создается впервые.
@PreDestroy Вызывается, когда бин удаляется из пула бинов или уничтожается.
@PostActivate Вызывается, когда бин загружается для использования.
@PrePassivate Вызывается, когда бин возвращается в пул бинов.

Ниже приведен список аннотаций обратного вызова для бина, управляемого сообщениями.

аннотирование Описание
@PostConstruct Вызывается, когда бин создается впервые.
@PreDestroy Вызывается, когда бин удаляется из пула бинов или уничтожается.

Ниже приведен список аннотаций обратного вызова для объекта управления данными:

аннотирование Описание
@PrePersist Вызывается, когда объект создается в базе данных.
@PostPersist Вызывается после создания объекта в базе данных.
@PreRemove Вызывается, когда объект удаляется из базы данных.
@PostRemove Вызывается после удаления объекта из базы данных.
@PreUpdate Вызывается до обновления объекта в базе данных.
@PostLoad Вызывается, когда запись извлекается из базы данных и загружается в объект.

Пример приложения

Давайте создадим тестовое EJB-приложение для тестирования различных обратных вызовов в EJB.

шаг Описание
1

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.stateless, как описано в главе EJB — Создание приложения . Вы также можете использовать проект, созданный в главе EJB — Постоянство как таковой для этой главы, чтобы добавить различные обратные вызовы в EJB.

2

Создайте LibrarySessionBean.java и LibrarySessionBeanRemote, как описано в главе EJB — Создание приложения . Сохраните остальные файлы без изменений.

3

Используйте Бины, созданные в главе EJB — Постоянство . Добавьте методы обратного вызова, как показано ниже. Сохраните остальные файлы без изменений.

4

Создайте Java-класс BookCallbackListener в пакете com.tutorialspoint.callback . Этот класс демонстрирует разделение методов обратного вызова.

5

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

6

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

7

Теперь создайте EJB-клиент, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» .

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.stateless, как описано в главе EJB — Создание приложения . Вы также можете использовать проект, созданный в главе EJB — Постоянство как таковой для этой главы, чтобы добавить различные обратные вызовы в EJB.

Создайте LibrarySessionBean.java и LibrarySessionBeanRemote, как описано в главе EJB — Создание приложения . Сохраните остальные файлы без изменений.

Используйте Бины, созданные в главе EJB — Постоянство . Добавьте методы обратного вызова, как показано ниже. Сохраните остальные файлы без изменений.

Создайте Java-класс BookCallbackListener в пакете com.tutorialspoint.callback . Этот класс демонстрирует разделение методов обратного вызова.

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

Теперь создайте EJB-клиент, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» .

EJBComponent (модуль 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();
    
}
  • Как только вы развернете проект EjbComponent в JBOSS, обратите внимание на журнал jboss.

  • JBoss автоматически создал запись JNDI для нашего сессионного компонента — LibraryPersistentBean / remote .

  • Мы будем использовать эту строку поиска для получения удаленного бизнес-объекта типа — com.tutorialspoint.stateless.LibraryPersistentBeanRemote

Как только вы развернете проект EjbComponent в JBOSS, обратите внимание на журнал jboss.

JBoss автоматически создал запись JNDI для нашего сессионного компонента — LibraryPersistentBean / remote .

Мы будем использовать эту строку поиска для получения удаленного бизнес-объекта типа — com.tutorialspoint.stateless.LibraryPersistentBeanRemote

Вывод журнала сервера приложений 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 (клиент 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
  • Эти свойства используются для инициализации объекта InitialContext сервиса именования java.

  • Объект InitialContext будет использоваться для поиска сессионного компонента без сохранения состояния.

Эти свойства используются для инициализации объекта InitialContext сервиса именования java.

Объект InitialContext будет использоваться для поиска сессионного компонента без сохранения состояния.

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 выполняет следующие задачи —

  • Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

  • В методе testStatelessEjb () поиск jndi выполняется с именем — «LibrarySessionBean / remote» для получения удаленного бизнес-объекта (EJB без сохранения состояния).

  • Затем пользователю показывается пользовательский интерфейс магазина библиотеки, и ему / ей предлагается ввести выбор.

  • Если пользователь вводит 1, система запрашивает имя книги и сохраняет книгу, используя метод addBook () сессионного компонента без сохранения состояния. Сессия Бин хранит книгу в базе данных.

  • Если пользователь вводит 2, система получает книги, используя метод getBooks () сессионного компонента без сохранения состояния, и завершает работу.

Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

В методе testStatelessEjb () поиск jndi выполняется с именем — «LibrarySessionBean / remote» для получения удаленного бизнес-объекта (EJB без сохранения состояния).

Затем пользователю показывается пользовательский интерфейс магазина библиотеки, и ему / ей предлагается ввести выбор.

Если пользователь вводит 1, система запрашивает имя книги и сохраняет книгу, используя метод addBook () сессионного компонента без сохранения состояния. Сессия Бин хранит книгу в базе данных.

Если пользователь вводит 2, система получает книги, используя метод getBooks () сессионного компонента без сохранения состояния, и завершает работу.

Запустите клиент для доступа к EJB

Найдите EJBTester.java в проводнике проекта. Щелкните правой кнопкой мыши класс EJBTester и выберите файл запуска .

Проверьте следующий вывод в консоли 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)

Вывод журнала сервера приложений JBoss

Вы можете найти следующие записи обратного вызова в журнале 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
...

EJB — Таймер Сервис

Служба таймера — это механизм, с помощью которого можно построить запланированное приложение. Например, формирование зарплатной квитанции 1-го числа каждого месяца. В спецификации EJB 3.0 указана аннотация @Timeout, которая помогает при программировании службы EJB в компоненте, не поддерживающем состояние или управляемом сообщениями. EJB Container вызывает метод, который аннотируется @Timeout.

Служба таймера EJB — это служба, предоставляемая контейнером EJB, которая помогает создавать таймер и планировать обратный вызов по истечении таймера.

Шаги по созданию таймера

Внедрить SessionContext в bean-компонент с помощью аннотации @Resource —

@Stateless
public class TimerSessionBean {

   @Resource
   private SessionContext context;
   ...
}

Используйте объект SessionContext, чтобы получить TimerService и создать таймер. Время прохождения в миллисекундах и сообщение.

public void createTimer(long duration) {
   context.getTimerService().createTimer(duration, "Hello World!");
}

Шаги по использованию таймера

Используйте аннотацию @Timeout для метода. Возвращаемый тип должен быть void и передавать параметр типа Timer. Мы отменяем таймер после первого выполнения, иначе он продолжит работать через фиксированные интервалы.

@Timeout
public void timeOutHandler(Timer timer) {
   System.out.println("timeoutHandler : " + timer.getInfo());        
   timer.cancel();
}

Пример приложения

Давайте создадим тестовое приложение EJB для тестирования службы таймера в EJB.

шаг Описание
1

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.timer, как описано в главе EJB — Создание приложения .

2

Создайте TimerSessionBean.java и TimerSessionBeanRemote, как описано в главе EJB — Создание приложения . Сохраните остальные файлы без изменений.

3

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

4

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

5

Теперь создайте EJB-клиент, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» .

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.timer, как описано в главе EJB — Создание приложения .

Создайте TimerSessionBean.java и TimerSessionBeanRemote, как описано в главе EJB — Создание приложения . Сохраните остальные файлы без изменений.

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

Теперь создайте EJB-клиент, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» .

EJBComponent (модуль 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);
}
  • Как только вы развернете проект EjbComponent в JBOSS, обратите внимание на журнал jboss.

  • JBoss автоматически создал запись JNDI для нашего сессионного компонента — TimerSessionBean / remote .

  • Мы будем использовать эту строку поиска для получения удаленного бизнес-объекта типа — com.tutorialspoint.timer.TimerSessionBeanRemote

Как только вы развернете проект EjbComponent в JBOSS, обратите внимание на журнал jboss.

JBoss автоматически создал запись JNDI для нашего сессионного компонента — TimerSessionBean / remote .

Мы будем использовать эту строку поиска для получения удаленного бизнес-объекта типа — com.tutorialspoint.timer.TimerSessionBeanRemote

Вывод журнала сервера приложений 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 (клиент 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
  • Эти свойства используются для инициализации объекта InitialContext сервиса именования java.

  • Объект InitialContext будет использоваться для поиска сессионного компонента без сохранения состояния.

Эти свойства используются для инициализации объекта InitialContext сервиса именования java.

Объект InitialContext будет использоваться для поиска сессионного компонента без сохранения состояния.

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 выполняет следующие задачи.

  • Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

  • В методе testTimerService () поиск jndi выполняется с именем — «TimerSessionBean / remote» для получения удаленного бизнес-объекта (таймера без сохранения состояния EJB).

  • Затем createTimer вызывается, передавая 2000 миллисекунд как время по расписанию.

  • Контейнер EJB вызывает метод timeoutHandler через 2 секунды.

Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

В методе testTimerService () поиск jndi выполняется с именем — «TimerSessionBean / remote» для получения удаленного бизнес-объекта (таймера без сохранения состояния EJB).

Затем createTimer вызывается, передавая 2000 миллисекунд как время по расписанию.

Контейнер EJB вызывает метод timeoutHandler через 2 секунды.

Запустите клиент для доступа к EJB

Найдите EJBTester.java в проводнике проекта. Щелкните правой кнопкой мыши класс EJBTester и выберите файл запуска .

Проверьте следующий вывод в консоли Netbeans.

run:
[Wed Jun 19 11:35:47 IST 2013]timer created.
BUILD SUCCESSFUL (total time: 0 seconds)

Вывод журнала сервера приложений JBoss

Вы можете найти следующие записи обратного вызова в журнале JBoss

...
11:35:49,555 INFO  [STDOUT] timeoutHandler : Hello World!
...

EJB — Внедрение зависимостей

Спецификация EJB 3.0 предоставляет аннотации, которые можно применять к полям или методам установки для внедрения зависимостей. Контейнер EJB использует глобальный реестр JNDI для определения зависимости. Следующие аннотации используются в EJB 3.0 для внедрения зависимостей.

  • @EJB — используется для вставки другой ссылки на EJB.

  • @Resource — используется для внедрения источника данных или одноэлементных сервисов, таких как sessionContext, timerService и т. Д.

@EJB — используется для вставки другой ссылки на EJB.

@Resource — используется для внедрения источника данных или одноэлементных сервисов, таких как sessionContext, timerService и т. Д.

Шаги по использованию @EJB

@EJB можно использовать в полях или в методах следующим образом:

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;
   }
   ...
}

Шаги по использованию @Resource

@Resource обычно используется для внедрения синглетонов, предоставляемых EJB-контейнером.

public class LibraryMessageBean implements MessageListener {
   @Resource
   private MessageDrivenContext mdctx;  
   ...
}

Пример приложения

Давайте создадим тестовое EJB-приложение для тестирования Dependency Injection Service в EJB.

шаг Описание
1

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.timer, как описано в главе EJB — Создание приложения .

2

Используйте Beans, созданные в главе EJB — Message Driven Bean . Сохраните остальные файлы без изменений.

3

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

4

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

5

Теперь создайте EJB-клиент, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» .

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.timer, как описано в главе EJB — Создание приложения .

Используйте Beans, созданные в главе EJB — Message Driven Bean . Сохраните остальные файлы без изменений.

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

Теперь создайте EJB-клиент, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» .

EJBComponent (модуль 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 (клиент 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 выполняет следующие задачи —

  • Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

  • В методе testStatefulEjb () поиск jndi выполняется с именем «/ queue / BookQueue», чтобы получить ссылку на очередь, доступную в Jboss. Затем отправитель создается с использованием сеанса очереди.

  • Затем пользователю показывается пользовательский интерфейс хранилища библиотеки, и ему / ей предлагается ввести выбор.

  • Если пользователь вводит 1, система запрашивает имя книги, а отправитель отправляет имя книги в очередь. Когда контейнер JBoss получает это сообщение в очереди, он вызывает метод onMessage нашего бина, управляемого сообщениями. Наш компонент, управляемый сообщениями, затем сохраняет книгу, используя метод addBook () сессионного компонента с сохранением состояния. Сессионный компонент сохраняет книгу в базе данных с помощью вызова EntityManager.

  • Если пользователь вводит 2, тогда выполняется другой поиск jndi с именем — «LibraryStatefulSessionBean / remote», чтобы снова получить удаленный бизнес-объект (EJB с сохранением состояния) и выполнить распечатку книг.

Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

В методе testStatefulEjb () поиск jndi выполняется с именем «/ queue / BookQueue», чтобы получить ссылку на очередь, доступную в Jboss. Затем отправитель создается с использованием сеанса очереди.

Затем пользователю показывается пользовательский интерфейс хранилища библиотеки, и ему / ей предлагается ввести выбор.

Если пользователь вводит 1, система запрашивает имя книги, а отправитель отправляет имя книги в очередь. Когда контейнер JBoss получает это сообщение в очереди, он вызывает метод onMessage нашего бина, управляемого сообщениями. Наш компонент, управляемый сообщениями, затем сохраняет книгу, используя метод addBook () сессионного компонента с сохранением состояния. Сессионный компонент сохраняет книгу в базе данных с помощью вызова EntityManager.

Если пользователь вводит 2, тогда выполняется другой поиск jndi с именем — «LibraryStatefulSessionBean / remote», чтобы снова получить удаленный бизнес-объект (EJB с сохранением состояния) и выполнить распечатку книг.

Запустите клиент для доступа к EJB

Найдите EJBTester.java в проводнике проекта. Щелкните правой кнопкой мыши класс EJBTester и выберите файл запуска .

Проверьте следующий вывод в консоли 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)

Вывод, показанный выше, гласит, что наш управляемый сообщениями компонент принимает сообщение и сохраняет книгу в постоянном хранилище, а книги извлекаются из базы данных.

Наш управляемый сообщениями bean-компонент использует LibraryPersistentBean, внедренный в него с помощью аннотации @EJB, и в случае исключения MessageDrivenContext, объект используется для отката транзакции.

EJB — Перехватчики

EJB 3.0 предоставляет спецификацию для перехвата вызовов бизнес-методов с использованием методов, аннотированных аннотацией @AroundInvoke. Метод перехватчика вызывается ejbContainer до его перехвата вызовом бизнес-метода. Ниже приведен пример сигнатуры метода перехватчика.

@AroundInvoke
public Object methodInterceptor(InvocationContext ctx) throws Exception {
   System.out.println("*** Intercepting call to LibraryBean method: " 
   + ctx.getMethod().getName());
   return ctx.proceed();
}

Методы перехватчика могут быть применены или связаны на трех уровнях.

  • По умолчанию — Перехватчик по умолчанию вызывается для каждого компонента в пределах развертывания. Перехватчик по умолчанию может применяться только через xml (ejb-jar.xml).

  • Класс — Перехватчик уровня класса вызывается для каждого метода компонента. Перехватчик уровня класса может применяться как с помощью аннотации через xml (ejb-jar.xml).

  • Метод — метод перехватчика уровня вызывается для определенного метода компонента. Перехватчик уровня метода может применяться как с помощью аннотации через xml (ejb-jar.xml).

По умолчанию — Перехватчик по умолчанию вызывается для каждого компонента в пределах развертывания. Перехватчик по умолчанию может применяться только через xml (ejb-jar.xml).

Класс — Перехватчик уровня класса вызывается для каждого метода компонента. Перехватчик уровня класса может применяться как с помощью аннотации через xml (ejb-jar.xml).

Метод — метод перехватчика уровня вызывается для определенного метода компонента. Перехватчик уровня метода может применяться как с помощью аннотации через xml (ejb-jar.xml).

Мы обсуждаем перехватчик уровня класса здесь.

Класс перехватчика

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

Удаленный интерфейс

import javax.ejb.Remote;

@Remote
public interface LibraryBeanRemote {
   //add business method declarations
}

Перехваченный безгражданский EJB

@Interceptors ({BusinessInterceptor.class})
@Stateless
public class LibraryBean implements LibraryBeanRemote {
   //implement business method 
}

Пример приложения

Давайте создадим тестовое EJB-приложение для проверки перехваченного EJB без сохранения состояния.

шаг Описание
1

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.interceptor, как описано в главе EJB — Создание приложения . Вы также можете использовать проект, созданный в главе EJB — Создание приложения как таковой, для понимания перехваченных концепций EJB.

2

Создайте LibraryBean.java и LibraryBeanRemote в пакете com.tutorialspoint.interceptor, как описано в главе EJB — Создание приложения . Сохраните остальные файлы без изменений.

3

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

4

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

5

Теперь создайте клиент ejb, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» .

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.interceptor, как описано в главе EJB — Создание приложения . Вы также можете использовать проект, созданный в главе EJB — Создание приложения как таковой, для понимания перехваченных концепций EJB.

Создайте LibraryBean.java и LibraryBeanRemote в пакете com.tutorialspoint.interceptor, как описано в главе EJB — Создание приложения . Сохраните остальные файлы без изменений.

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

Теперь создайте клиент ejb, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» .

EJBComponent (модуль 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;
   }   
}
  • Как только вы развернете проект EjbComponent в JBOSS, обратите внимание на журнал jboss.

  • JBoss автоматически создал запись JNDI для нашего сессионного компонента — LibraryBean / remote .

  • Мы будем использовать эту строку поиска для получения удаленного бизнес-объекта типа — com.tutorialspoint.interceptor.LibraryBeanRemote

Как только вы развернете проект EjbComponent в JBOSS, обратите внимание на журнал jboss.

JBoss автоматически создал запись JNDI для нашего сессионного компонента — LibraryBean / remote .

Мы будем использовать эту строку поиска для получения удаленного бизнес-объекта типа — com.tutorialspoint.interceptor.LibraryBeanRemote

Вывод журнала сервера приложений 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 (клиент 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
  • Эти свойства используются для инициализации объекта InitialContext сервиса именования java.

  • Объект InitialContext будет использоваться для поиска сессионного компонента без сохранения состояния.

Эти свойства используются для инициализации объекта InitialContext сервиса именования java.

Объект InitialContext будет использоваться для поиска сессионного компонента без сохранения состояния.

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 выполняет следующие задачи —

  • Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

  • В методе testInterceptedEjb () поиск jndi выполняется с именем — «LibraryBean / remote» для получения удаленного бизнес-объекта (EJB без сохранения состояния).

  • Затем пользователю показывается пользовательский интерфейс магазина библиотеки, и ему / ей предлагается ввести выбор.

  • Если пользователь вводит 1, система запрашивает имя книги и сохраняет книгу, используя метод addBook () сессионного компонента без сохранения состояния. Сессионный компонент хранит книгу в своей переменной экземпляра.

  • Если пользователь вводит 2, система получает книги с использованием метода getBooks () сессионного компонента без сохранения состояния и завершает работу.

Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

В методе testInterceptedEjb () поиск jndi выполняется с именем — «LibraryBean / remote» для получения удаленного бизнес-объекта (EJB без сохранения состояния).

Затем пользователю показывается пользовательский интерфейс магазина библиотеки, и ему / ей предлагается ввести выбор.

Если пользователь вводит 1, система запрашивает имя книги и сохраняет книгу, используя метод addBook () сессионного компонента без сохранения состояния. Сессионный компонент хранит книгу в своей переменной экземпляра.

Если пользователь вводит 2, система получает книги с использованием метода getBooks () сессионного компонента без сохранения состояния и завершает работу.

Запустите клиент для доступа к EJB

Найдите EJBTester.java в проводнике проекта. Щелкните правой кнопкой мыши класс EJBTester и выберите файл запуска .

Проверьте следующий вывод в консоли 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)

Вывод журнала сервера приложений JBoss

Проверьте следующий вывод в выводе журнала сервера приложений 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 — Встраиваемые объекты

EJB 3.0 предоставляет возможность встраивания JAVA POJO (Plain Old Java Object) в объектный компонент и позволяет отображать имена столбцов с помощью методов встроенного класса POJO. Встраиваемый Java-POJO должен быть аннотирован как @Embeddable.

@Embeddable
public class Publisher implements Serializable{
   private String name;
   private String address;
   ...
}

Вышеуказанный класс может быть встроен с использованием аннотации @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;
   }
   ...
}

Пример приложения

Давайте создадим тестовое EJB-приложение для тестирования встроенных объектов в EJB 3.0.

шаг Описание
1

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.entity, как описано в главе EJB — Создание приложения . Пожалуйста, используйте проект, созданный в главе EJB — Постоянство как таковой для этой главы, чтобы понять встроенные объекты в концепциях EJB.

2

Создайте Publisher.java в пакете com.tutorialspoint.entity, как описано в главе EJB — Создание приложения . Сохраните остальные файлы без изменений.

3

Создайте Book.java в пакете com.tutorialspoint.entity . Используйте EJB — главу Постоянство в качестве ссылки. Сохраните остальные файлы без изменений.

4

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

5

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

6

Теперь создайте EJB-клиент, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» .

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.entity, как описано в главе EJB — Создание приложения . Пожалуйста, используйте проект, созданный в главе EJB — Постоянство как таковой для этой главы, чтобы понять встроенные объекты в концепциях EJB.

Создайте Publisher.java в пакете com.tutorialspoint.entity, как описано в главе EJB — Создание приложения . Сохраните остальные файлы без изменений.

Создайте Book.java в пакете com.tutorialspoint.entity . Используйте EJB — главу Постоянство в качестве ссылки. Сохраните остальные файлы без изменений.

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

Теперь создайте EJB-клиент, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» .

Создать / изменить таблицу книг

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 (модуль 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();
   }
}
  • Как только вы развернете проект EjbComponent в JBOSS, обратите внимание на журнал jboss.

  • JBoss автоматически создал запись JNDI для нашего сессионного компонента — LibraryPersistentBean / remote .

  • Мы будем использовать эту строку поиска для получения удаленного бизнес-объекта типа — com.tutorialspoint.interceptor.LibraryPersistentBeanRemote

Как только вы развернете проект EjbComponent в JBOSS, обратите внимание на журнал jboss.

JBoss автоматически создал запись JNDI для нашего сессионного компонента — LibraryPersistentBean / remote .

Мы будем использовать эту строку поиска для получения удаленного бизнес-объекта типа — com.tutorialspoint.interceptor.LibraryPersistentBeanRemote

Вывод журнала сервера приложений 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 (клиент 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
  • Эти свойства используются для инициализации объекта InitialContext сервиса именования java.

  • Объект InitialContext будет использоваться для поиска сессионного компонента без сохранения состояния.

Эти свойства используются для инициализации объекта InitialContext сервиса именования java.

Объект InitialContext будет использоваться для поиска сессионного компонента без сохранения состояния.

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 выполняет следующие задачи —

  • Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

  • В методе testInterceptedEjb () поиск jndi выполняется с именем — «LibraryPersistenceBean / remote» для получения удаленного бизнес-объекта (EJB без сохранения состояния).

  • Затем пользователю показывается пользовательский интерфейс хранилища библиотеки, и ему / ей предлагается ввести выбор.

  • Если пользователь вводит 1, система запрашивает имя книги и сохраняет книгу, используя метод addBook () сессионного компонента без сохранения состояния. Сессия Бин хранит книгу в базе данных.

  • Если пользователь вводит 2, система получает книги с использованием метода getBooks () сессионного компонента без сохранения состояния и завершает работу.

Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

В методе testInterceptedEjb () поиск jndi выполняется с именем — «LibraryPersistenceBean / remote» для получения удаленного бизнес-объекта (EJB без сохранения состояния).

Затем пользователю показывается пользовательский интерфейс хранилища библиотеки, и ему / ей предлагается ввести выбор.

Если пользователь вводит 1, система запрашивает имя книги и сохраняет книгу, используя метод addBook () сессионного компонента без сохранения состояния. Сессия Бин хранит книгу в базе данных.

Если пользователь вводит 2, система получает книги с использованием метода getBooks () сессионного компонента без сохранения состояния и завершает работу.

Запустите клиент для доступа к EJB

Найдите EJBTester.java в проводнике проекта. Щелкните правой кнопкой мыши класс EJBTester и выберите файл запуска .

Проверьте следующий вывод в консоли 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 — Blob / Clobs

EJB 3.0 обеспечивает поддержку типов Blob и Clob с использованием аннотации @Lob. Следующие типы Java могут быть отображены с помощью аннотации @Lob.

  • java.sql.Blob
  • java.sql.Clob
  • байт[]
  • строка
  • Сериализуемый объект
@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;
   }
   ...
}

Пример приложения

Давайте создадим тестовое EJB-приложение для тестирования поддержки BLOB / Clob в EJB 3.0.

шаг Описание
1

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.entity, как описано в главе EJB — Создание приложения . Пожалуйста, используйте проект, созданный в главе EJB — Постоянство как таковой для этой главы, чтобы понять объекты clob / blob в концепциях ejb.

2

Создайте Book.java в пакете com.tutorialspoint.entity . Используйте EJB — главу Постоянство в качестве ссылки. Сохраните остальные файлы без изменений.

3

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

4

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

5

Теперь создайте EJB-клиент, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» .

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.entity, как описано в главе EJB — Создание приложения . Пожалуйста, используйте проект, созданный в главе EJB — Постоянство как таковой для этой главы, чтобы понять объекты clob / blob в концепциях ejb.

Создайте Book.java в пакете com.tutorialspoint.entity . Используйте EJB — главу Постоянство в качестве ссылки. Сохраните остальные файлы без изменений.

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

Теперь создайте EJB-клиент, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» .

Создать / изменить таблицу книг

CREATE TABLE book (
   id     integer PRIMARY KEY,
   name   varchar(50)
);
Alter table book add image bytea;
Alter table book add xml text;

EJBComponent (модуль 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();
   }
}
  • Как только вы развернете проект EjbComponent в JBOSS, обратите внимание на журнал jboss.

  • JBoss автоматически создал запись JNDI для нашего сессионного компонента — LibraryPersistentBean / remote .

  • Мы будем использовать эту строку поиска для получения удаленного бизнес-объекта типа — com.tutorialspoint.interceptor.LibraryPersistentBeanRemote

Как только вы развернете проект EjbComponent в JBOSS, обратите внимание на журнал jboss.

JBoss автоматически создал запись JNDI для нашего сессионного компонента — LibraryPersistentBean / remote .

Мы будем использовать эту строку поиска для получения удаленного бизнес-объекта типа — com.tutorialspoint.interceptor.LibraryPersistentBeanRemote

Вывод журнала сервера приложений 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 (клиент 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
  • Эти свойства используются для инициализации объекта InitialContext сервиса именования java.

  • Объект InitialContext будет использоваться для поиска сессионного компонента без сохранения состояния.

Эти свойства используются для инициализации объекта InitialContext сервиса именования java.

Объект InitialContext будет использоваться для поиска сессионного компонента без сохранения состояния.

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 выполняет следующие задачи.

  • Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

  • В методе testInterceptedEjb () поиск jndi выполняется с именем — «LibraryPersistenceBean / remote» для получения удаленного бизнес-объекта (EJB без сохранения состояния).

  • Затем пользователю показывается пользовательский интерфейс хранилища библиотеки, и ему / ей предлагается ввести выбор.

  • Если пользователь вводит 1, система запрашивает имя книги и сохраняет книгу, используя метод addBook () сессионного компонента без сохранения состояния. Сессия Бин хранит книгу в базе данных.

  • Если пользователь вводит 2, система получает книги с использованием метода getBooks () сессионного компонента без сохранения состояния и завершает работу.

Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

В методе testInterceptedEjb () поиск jndi выполняется с именем — «LibraryPersistenceBean / remote» для получения удаленного бизнес-объекта (EJB без сохранения состояния).

Затем пользователю показывается пользовательский интерфейс хранилища библиотеки, и ему / ей предлагается ввести выбор.

Если пользователь вводит 1, система запрашивает имя книги и сохраняет книгу, используя метод addBook () сессионного компонента без сохранения состояния. Сессия Бин хранит книгу в базе данных.

Если пользователь вводит 2, система получает книги с использованием метода getBooks () сессионного компонента без сохранения состояния и завершает работу.

Запустите клиент для доступа к EJB

Найдите EJBTester.java в проводнике проекта. Щелкните правой кнопкой мыши класс EJBTester и выберите файл запуска .

Проверьте следующий вывод в консоли 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)

EJB — Сделки

Транзакция — это единица рабочих элементов, которая соответствует свойствам ACID. КИСЛОТА означает Атомный, Последовательный, Изолированный и Прочный.

  • Атомная — если какой-либо из рабочих элементов потерпит неудачу, весь блок будет считаться неисправным. Успех означает, что все пункты выполнены успешно.

  • Согласованный — транзакция должна поддерживать систему в согласованном состоянии.

  • Изолированный — каждая транзакция выполняется независимо от любой другой транзакции.

  • Долговечный — Транзакция должна выдерживать системный сбой, если она была выполнена или зафиксирована.

Атомная — если какой-либо из рабочих элементов потерпит неудачу, весь блок будет считаться неисправным. Успех означает, что все пункты выполнены успешно.

Согласованный — транзакция должна поддерживать систему в согласованном состоянии.

Изолированный — каждая транзакция выполняется независимо от любой другой транзакции.

Долговечный — Транзакция должна выдерживать системный сбой, если она была выполнена или зафиксирована.

Контейнер / серверы EJB являются серверами транзакций и обрабатывают распространение контекста транзакций и распределенные транзакции. Транзакции могут управляться контейнером или пользовательской обработкой кода в коде компонента.

  • Управляемые контейнером транзакции — в этом типе контейнер управляет состояниями транзакции.

  • Управляемые Бином Транзакции — В этом типе разработчик управляет жизненным циклом состояний транзакции.

Управляемые контейнером транзакции — в этом типе контейнер управляет состояниями транзакции.

Управляемые Бином Транзакции — В этом типе разработчик управляет жизненным циклом состояний транзакции.

Управляемые контейнером транзакции

EJB 3.0 указал следующие атрибуты транзакций, которые реализуют EJB-контейнеры:

  • ТРЕБУЕТСЯ — указывает, что бизнес-метод должен выполняться внутри транзакции, в противном случае для этого метода будет запущена новая транзакция.

  • REQUIRES_NEW — указывает, что для бизнес-метода должна быть запущена новая транзакция.

  • ПОДДЕРЖКА — Указывает, что бизнес-метод будет выполняться как часть транзакции.

  • NOT_SUPPORTED — указывает, что бизнес-метод не должен выполняться как часть транзакции.

  • ОБЯЗАТЕЛЬНО — Указывает, что бизнес-метод будет выполнен как часть транзакции, в противном случае будет сгенерировано исключение.

  • НИКОГДА — Указывает, что если бизнес-метод выполняется как часть транзакции, то будет выдано исключение.

ТРЕБУЕТСЯ — указывает, что бизнес-метод должен выполняться внутри транзакции, в противном случае для этого метода будет запущена новая транзакция.

REQUIRES_NEW — указывает, что для бизнес-метода должна быть запущена новая транзакция.

ПОДДЕРЖКА — Указывает, что бизнес-метод будет выполняться как часть транзакции.

NOT_SUPPORTED — указывает, что бизнес-метод не должен выполняться как часть транзакции.

ОБЯЗАТЕЛЬНО — Указывает, что бизнес-метод будет выполнен как часть транзакции, в противном случае будет сгенерировано исключение.

НИКОГДА — Указывает, что если бизнес-метод выполняется как часть транзакции, то будет выдано исключение.

пример

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
   }
}

Бизнес-метод createUserDetail () сделан Обязательным с помощью обязательной аннотации.

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

Бизнес-метод createUser () использует createUserDetail (). Если во время вызова createUser () возникла исключительная ситуация, и объект User не был создан, объект UserDetail также не будет создан.

Управляемые Бином Транзакции

В управляемых компонентом транзакциях транзакциями можно управлять путем обработки исключений на уровне приложения.

Ниже приведены ключевые моменты, которые необходимо учитывать:

  • Начало — когда начинать транзакцию в бизнес-методе.

  • Успех — определить сценарий успеха, когда транзакция должна быть зафиксирована.

  • Failed (Сбой) — определение сценария сбоя, когда транзакция подлежит откату.

Начало — когда начинать транзакцию в бизнес-методе.

Успех — определить сценарий успеха, когда транзакция должна быть зафиксирована.

Failed (Сбой) — определение сценария сбоя, когда транзакция подлежит откату.

пример

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{
   }
}

В этом примере мы использовали интерфейс UserTransaction, чтобы отметить начало транзакции с помощью вызова метода userTransaction.begin () . Мы отмечаем завершение транзакции, используя метод userTransaction.commit (), и если во время транзакции произошло какое-либо исключение, мы откатываем завершенную транзакцию с использованием вызова метода userTransaction.rollback () .

EJB — Безопасность

Безопасность — главная проблема любого приложения уровня предприятия. Он включает в себя идентификацию пользователя (ей) или системы, обращающейся к приложению. Основываясь на идентификации, он разрешает или запрещает доступ к ресурсам в приложении. Контейнер EJB управляет стандартными проблемами безопасности или может быть настроен для решения каких-либо конкретных проблем безопасности.

Важные условия безопасности

  • Аутентификация — это процесс, обеспечивающий аутентификацию пользователя, обращающегося к системе или приложению.

  • Авторизация — это процесс, гарантирующий, что аутентичный пользователь имеет право доступа к системным ресурсам.

  • Пользователь — Пользователь представляет клиента или систему, которая обращается к приложению.

  • Группы пользователей — пользователи могут входить в группу с определенными правами доступа. Например, группа администраторов.

  • Роли пользователя — Роли определяют уровень полномочий, которые пользователь имеет или права доступа к системному ресурсу.

Аутентификация — это процесс, обеспечивающий аутентификацию пользователя, обращающегося к системе или приложению.

Авторизация — это процесс, гарантирующий, что аутентичный пользователь имеет право доступа к системным ресурсам.

Пользователь — Пользователь представляет клиента или систему, которая обращается к приложению.

Группы пользователей — пользователи могут входить в группу с определенными правами доступа. Например, группа администраторов.

Роли пользователя — Роли определяют уровень полномочий, которые пользователь имеет или права доступа к системному ресурсу.

Контейнер Управляемая безопасность

EJB 3.0 указал следующие атрибуты / аннотации безопасности, которые реализуют EJB-контейнеры.

  • DeclareRoles — указывает, что класс будет принимать объявленные роли. Аннотации применяются на уровне класса.

  • RolesAllowed — указывает, что метод может быть доступен пользователю с указанной ролью. Может применяться на уровне класса, в результате чего все методы класса могут быть доступны для покупки указанной роли.

  • PermitAll — указывает, что бизнес-метод доступен для всех. Это может быть применено в классе, а также на уровне метода.

  • DenyAll — указывает, что бизнес-метод не доступен ни одному из пользователей, указанных на уровне класса или метода.

DeclareRoles — указывает, что класс будет принимать объявленные роли. Аннотации применяются на уровне класса.

RolesAllowed — указывает, что метод может быть доступен пользователю с указанной ролью. Может применяться на уровне класса, в результате чего все методы класса могут быть доступны для покупки указанной роли.

PermitAll — указывает, что бизнес-метод доступен для всех. Это может быть применено в классе, а также на уровне метода.

DenyAll — указывает, что бизнес-метод не доступен ни одному из пользователей, указанных на уровне класса или метода.

пример

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
   } 
}

Конфигурация безопасности

Роли карты и группы пользователей в файле конфигурации.

<?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>

EJB — JNDI Привязки

JNDI расшифровывается как Java Naming and Directory Interface. Это набор API и сервисных интерфейсов. Java-приложения используют JNDI для именования и служб каталогов. В контексте EJB есть два термина.

  • Привязка — это относится к присвоению имени объекту EJB, который можно использовать позже.

  • Lookup — это относится к поиску и получению объекта EJB.

Привязка — это относится к присвоению имени объекту EJB, который можно использовать позже.

Lookup — это относится к поиску и получению объекта EJB.

В Jboss сессионные компоненты по умолчанию связаны в JNDI в следующем формате.

  • местный — EJB-имя / местный

  • удаленный — EJB-имя / удаленный

местный — EJB-имя / местный

удаленный — EJB-имя / удаленный

В случае, если EJB связан с файлом <application-name> .ear, то по умолчанию используется следующий формат:

  • local — имя приложения / ejb-name / local

  • remote — имя приложения / ejb-name / remote

local — имя приложения / ejb-name / local

remote — имя приложения / ejb-name / remote

Пример привязки по умолчанию

Обратитесь к EJB — вывод консоли JBoss главы « Создание приложения ».

Вывод журнала сервера приложений 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
...

Индивидуальная привязка

Следующие аннотации могут быть использованы для настройки привязок JNDI по умолчанию —

  • local — org.jboss.ejb3.LocalBinding

  • удаленный — org.jboss.ejb3.RemoteBindings

local — org.jboss.ejb3.LocalBinding

удаленный — org.jboss.ejb3.RemoteBindings

Обновите LibrarySessionBean.java. Обратитесь к главе EJB — Создание приложения .

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;
    }
}

LibrarySessionBeanLocal

package com.tutorialspoint.stateless;
 
import java.util.List;
import javax.ejb.Local;
 
@Local
public interface LibrarySessionBeanLocal {
 
    void addBook(String bookName);
 
    List getBooks();
    
}

Создайте проект, разверните приложение в Jboss и проверьте следующий вывод в консоли 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 — отношения сущностей

EJB 3.0 предоставляет возможность определять отношения / отображения сущностей базы данных, такие как отношения один-к-одному, один-ко-многим, многие-к-одному и многие-ко-многим.

Ниже приведены соответствующие аннотации —

  • Один-к-одному — объекты имеют отношение один-к-одному. Например, пассажир может путешествовать по одному билету за раз.

  • Один-ко-многим — объекты имеют отношение один-ко-многим. Например, у отца может быть несколько детей.

  • Многие-к-одному — объекты имеют отношение многие-к-одному. Например, у нескольких детей есть мать-одиночка.

  • Многие ко многим — Объекты имеют отношение ко многим. Например, книга может иметь несколько авторов, а автор может написать несколько книг.

Один-к-одному — объекты имеют отношение один-к-одному. Например, пассажир может путешествовать по одному билету за раз.

Один-ко-многим — объекты имеют отношение один-ко-многим. Например, у отца может быть несколько детей.

Многие-к-одному — объекты имеют отношение многие-к-одному. Например, у нескольких детей есть мать-одиночка.

Многие ко многим — Объекты имеют отношение ко многим. Например, книга может иметь несколько авторов, а автор может написать несколько книг.

Мы продемонстрируем использование отображения ManyToMany здесь. Для представления отношений ManyToMany необходимы три следующие таблицы:

  • Книга — книжный стол, имеющий записи книг.

  • Автор — Автор таблицы, имеющий записи автора.

  • Book_Author — таблица «Автор книги», имеющая связь между вышеупомянутой таблицей «Книга» и «Автор».

Книга — книжный стол, имеющий записи книг.

Автор — Автор таблицы, имеющий записи автора.

Book_Author — таблица «Автор книги», имеющая связь между вышеупомянутой таблицей «Книга» и «Автор».

Создать таблицы

Создайте таблицу автора книги , book_author в базе данных 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 
);

Создать классы сущностей

@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;
   ...   
}

Используйте аннотацию ManyToMany в Book Entity.

@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;
   }
   ...
}

Пример приложения

Давайте создадим тестовое EJB-приложение для тестирования объектов отношений сущностей в EJB 3.0.

шаг Описание
1

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.entity, как описано в главе EJB — Создание приложения . Пожалуйста, используйте проект, созданный в главе EJB — Постоянство как таковой для этой главы, чтобы понять встроенные объекты в концепциях EJB.

2

Создайте Author.java в пакете com.tutorialspoint.entity, как описано в главе EJB — Создание приложения . Сохраните остальные файлы без изменений.

3

Создайте Book.java в пакете com.tutorialspoint.entity . Используйте EJB — главу Постоянство в качестве ссылки. Сохраните остальные файлы без изменений.

4

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

5

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

6

Теперь создайте EJB-клиент, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» .

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.entity, как описано в главе EJB — Создание приложения . Пожалуйста, используйте проект, созданный в главе EJB — Постоянство как таковой для этой главы, чтобы понять встроенные объекты в концепциях EJB.

Создайте Author.java в пакете com.tutorialspoint.entity, как описано в главе EJB — Создание приложения . Сохраните остальные файлы без изменений.

Создайте Book.java в пакете com.tutorialspoint.entity . Используйте EJB — главу Постоянство в качестве ссылки. Сохраните остальные файлы без изменений.

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

Теперь создайте EJB-клиент, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» .

EJBComponent (модуль EJB)

Author.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();
   }
}
  • Как только вы развернете проект EjbComponent в JBOSS, обратите внимание на журнал jboss.

  • JBoss автоматически создал запись JNDI для нашего сессионного компонента — LibraryPersistentBean / remote .

  • Мы будем использовать эту строку поиска для получения удаленного бизнес-объекта типа — com.tutorialspoint.interceptor.LibraryPersistentBeanRemote

Как только вы развернете проект EjbComponent в JBOSS, обратите внимание на журнал jboss.

JBoss автоматически создал запись JNDI для нашего сессионного компонента — LibraryPersistentBean / remote .

Мы будем использовать эту строку поиска для получения удаленного бизнес-объекта типа — com.tutorialspoint.interceptor.LibraryPersistentBeanRemote

Вывод журнала сервера приложений 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 (клиент 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
  • Эти свойства используются для инициализации объекта InitialContext сервиса именования java.

  • Объект InitialContext будет использоваться для поиска сессионного компонента без сохранения состояния.

Эти свойства используются для инициализации объекта InitialContext сервиса именования java.

Объект InitialContext будет использоваться для поиска сессионного компонента без сохранения состояния.

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 выполняет следующие задачи —

  • Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

  • В методе testInterceptedEjb () поиск jndi выполняется с именем — «LibraryPersistenceBean / remote» для получения удаленного бизнес-объекта (EJB без сохранения состояния).

  • Затем пользователю показывается пользовательский интерфейс хранилища библиотеки, и ему / ей предлагается ввести выбор.

  • Если пользователь вводит 1, система запрашивает имя книги и сохраняет книгу, используя метод addBook () сессионного компонента без сохранения состояния. Сессия Бин хранит книгу в базе данных.

  • Если пользователь вводит 2, система получает книги с использованием метода getBooks () сессионного компонента без сохранения состояния и завершает работу.

Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

В методе testInterceptedEjb () поиск jndi выполняется с именем — «LibraryPersistenceBean / remote» для получения удаленного бизнес-объекта (EJB без сохранения состояния).

Затем пользователю показывается пользовательский интерфейс хранилища библиотеки, и ему / ей предлагается ввести выбор.

Если пользователь вводит 1, система запрашивает имя книги и сохраняет книгу, используя метод addBook () сессионного компонента без сохранения состояния. Сессия Бин хранит книгу в базе данных.

Если пользователь вводит 2, система получает книги с использованием метода getBooks () сессионного компонента без сохранения состояния и завершает работу.

Запустите клиент для доступа к EJB

Найдите EJBTester.java в проводнике проекта. Щелкните правой кнопкой мыши класс EJBTester и выберите файл запуска .

Проверьте следующий вывод в консоли 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)

EJB — база данных доступа

В EJB 3.0 механизм персистентности используется для доступа к базе данных, в которой контейнер управляет операциями, связанными с базой данных. Разработчики могут обращаться к базе данных с помощью вызова API JDBC напрямую в бизнес-методах EJB.

Чтобы продемонстрировать доступ к базе данных в EJB, нам нужно выполнить следующие задачи:

  • Шаг 1 — Создать таблицу в базе данных.

  • Шаг 2 — Создайте EJB без состояния, имеющий дело со мной.

  • Шаг 3 — Обновите EJB без сохранения состояния. Добавьте методы для добавления записей и получения записей из базы данных через менеджер сущностей.

  • Шаг 4 — Клиент консольного приложения получит доступ к EJB без сохранения состояния для сохранения данных в базе данных.

Шаг 1 — Создать таблицу в базе данных.

Шаг 2 — Создайте EJB без состояния, имеющий дело со мной.

Шаг 3 — Обновите EJB без сохранения состояния. Добавьте методы для добавления записей и получения записей из базы данных через менеджер сущностей.

Шаг 4 — Клиент консольного приложения получит доступ к EJB без сохранения состояния для сохранения данных в базе данных.

Создать таблицу

Создать таблицу книг по умолчанию в базе данных postgres .

CREATE TABLE books (
   id     integer PRIMARY KEY,
   name   varchar(50)
);

Создать модельный класс

public class Book implements Serializable{
    
   private int id;
   private String name;

   public Book() {        
   }
   
   public int getId() {
      return id;
   }
   ...
}

Создать EJB без состояния

@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
   }
   ...
}

После создания модуля EJB нам нужен клиент для доступа к bean-компоненту без сохранения состояния, который мы собираемся создать в следующем разделе.

Пример приложения

Давайте создадим тестовое приложение EJB для проверки механизма доступа к базе данных EJB.

шаг Описание
1

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.entity, как описано в главе EJB — Создание приложения . Вы также можете использовать проект, созданный в главе EJB — Создание приложения как таковой, для понимания концепций доступа к данным EJB.

2

Создайте Book.java в пакете com.tutorialspoint.entity и измените его, как показано ниже.

3

Создайте LibraryPersistentBean.java и LibraryPersistentBeanRemote, как описано в главе EJB — Создание приложения, и измените их, как показано ниже.

4

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

5

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

6

Теперь создайте EJB-клиент, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» . Измените его, как показано ниже.

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.entity, как описано в главе EJB — Создание приложения . Вы также можете использовать проект, созданный в главе EJB — Создание приложения как таковой, для понимания концепций доступа к данным EJB.

Создайте Book.java в пакете com.tutorialspoint.entity и измените его, как показано ниже.

Создайте LibraryPersistentBean.java и LibraryPersistentBeanRemote, как описано в главе EJB — Создание приложения, и измените их, как показано ниже.

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

Теперь создайте EJB-клиент, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» . Измените его, как показано ниже.

EJBComponent (модуль 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;
   }
}

  • Как только вы развернете проект EjbComponent в JBOSS, обратите внимание на журнал jboss.

  • JBoss автоматически создал запись JNDI для нашего сессионного компонента — LibraryPersistentBean / remote .

  • Мы будем использовать эту строку поиска для получения удаленного бизнес-объекта типа — com.tutorialspoint.stateless.LibraryPersistentBeanRemote

Как только вы развернете проект EjbComponent в JBOSS, обратите внимание на журнал jboss.

JBoss автоматически создал запись JNDI для нашего сессионного компонента — LibraryPersistentBean / remote .

Мы будем использовать эту строку поиска для получения удаленного бизнес-объекта типа — com.tutorialspoint.stateless.LibraryPersistentBeanRemote

Вывод журнала сервера приложений 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 (клиент 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
  • Эти свойства используются для инициализации объекта InitialContext сервиса именования java.

  • Объект InitialContext будет использоваться для поиска сессионного компонента без сохранения состояния.

Эти свойства используются для инициализации объекта InitialContext сервиса именования java.

Объект InitialContext будет использоваться для поиска сессионного компонента без сохранения состояния.

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 выполняет следующие задачи —

  • Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

  • В методе testStatefulEjb () поиск jndi выполняется с именем «LibraryStatelessSessionBean / remote» для получения удаленного бизнес-объекта (EJB с состоянием).

  • Затем пользователю показывается пользовательский интерфейс магазина библиотеки, и ему / ей предлагается ввести выбор.

  • Если пользователь вводит 1, система запрашивает имя книги и сохраняет книгу, используя метод addBook () сессионного компонента без сохранения состояния. Сессионный компонент сохраняет книгу в базе данных с помощью вызова EntityManager.

  • Если пользователь вводит 2, система получает книги с использованием метода getBooks () сессионного компонента без сохранения состояния и завершает работу.

  • Затем выполняется другой поиск jndi с именем — «LibraryStatelessSessionBean / remote», чтобы снова получить удаленный бизнес-объект (с состоянием EJB) и составить список книг.

Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

В методе testStatefulEjb () поиск jndi выполняется с именем «LibraryStatelessSessionBean / remote» для получения удаленного бизнес-объекта (EJB с состоянием).

Затем пользователю показывается пользовательский интерфейс магазина библиотеки, и ему / ей предлагается ввести выбор.

Если пользователь вводит 1, система запрашивает имя книги и сохраняет книгу, используя метод addBook () сессионного компонента без сохранения состояния. Сессионный компонент сохраняет книгу в базе данных с помощью вызова EntityManager.

Если пользователь вводит 2, система получает книги с использованием метода getBooks () сессионного компонента без сохранения состояния и завершает работу.

Затем выполняется другой поиск jndi с именем — «LibraryStatelessSessionBean / remote», чтобы снова получить удаленный бизнес-объект (с состоянием EJB) и составить список книг.

Запустите клиент для доступа к EJB

Найдите EJBTester.java в проводнике проекта. Щелкните правой кнопкой мыши класс EJBTester и выберите файл запуска .

Проверьте следующий вывод в консоли 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 — язык запросов

EJB Query Language очень удобен для написания пользовательских запросов, не беспокоясь о деталях базы данных. Он очень похож на HQL, язык запросов Hibernate и часто называется EJBQL.

Чтобы продемонстрировать EJBQL в EJB, мы собираемся выполнить следующие задачи:

  • Шаг 1 — Создать таблицу в базе данных.

  • Шаг 2 — Создайте EJB без состояния, имеющий дело со мной.

  • Шаг 3 — Обновление EJB без сохранения состояния. Добавьте методы для добавления записей и получения записей из базы данных через менеджер сущностей.

  • Шаг 4 — Клиент консольного приложения получит доступ к EJB без сохранения состояния для сохранения данных в базе данных.

Шаг 1 — Создать таблицу в базе данных.

Шаг 2 — Создайте EJB без состояния, имеющий дело со мной.

Шаг 3 — Обновление EJB без сохранения состояния. Добавьте методы для добавления записей и получения записей из базы данных через менеджер сущностей.

Шаг 4 — Клиент консольного приложения получит доступ к EJB без сохранения состояния для сохранения данных в базе данных.

Создать таблицу

Создать таблицу книг по умолчанию в базе данных postgres .

CREATE TABLE books (
   id     integer PRIMARY KEY,
   name   varchar(50)
);

Создать модельный класс

public class Book implements Serializable{
    
   private int id;
   private String name;

   public Book() {        
   }
   
   public int getId() {
      return id;
   }
   ...
}

Создать EJB без состояния

@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
   }
   ...
}

После создания модуля EJB нам нужен клиент для доступа к bean-компоненту без сохранения состояния, который мы собираемся создать в следующем разделе.

Пример приложения

Давайте создадим тестовое приложение EJB для проверки механизма доступа к базе данных EJB.

шаг Описание
1

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.entity, как описано в главе EJB — Создание приложения . Вы также можете использовать проект, созданный в главе EJB — Создание приложения как таковой, для понимания концепций доступа к данным EJB.

2

Создайте Book.java в пакете com.tutorialspoint.entity и измените его, как показано ниже.

3

Создайте LibraryPersistentBean.java и LibraryPersistentBeanRemote, как описано в главе EJB — Создание приложения, и измените их, как показано ниже.

4

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

5

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

6

Теперь создайте EJB-клиент, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» . Измените его, как показано ниже.

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.entity, как описано в главе EJB — Создание приложения . Вы также можете использовать проект, созданный в главе EJB — Создание приложения как таковой, для понимания концепций доступа к данным EJB.

Создайте Book.java в пакете com.tutorialspoint.entity и измените его, как показано ниже.

Создайте LibraryPersistentBean.java и LibraryPersistentBeanRemote, как описано в главе EJB — Создание приложения, и измените их, как показано ниже.

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

Теперь создайте EJB-клиент, консольное приложение, аналогично тому, как описано в главе EJB — Создание приложения в разделе « Создание клиента для доступа к EJB» . Измените его, как показано ниже.

EJBComponent (модуль 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();
   }   
}
  • Как только вы развернете проект EjbComponent в JBOSS, обратите внимание на журнал jboss.

  • JBoss автоматически создал запись JNDI для нашего сессионного компонента — LibraryPersistentBean / remote .

  • Мы будем использовать эту строку поиска для получения удаленного бизнес-объекта типа — com.tutorialspoint.stateless.LibraryPersistentBeanRemote

Как только вы развернете проект EjbComponent в JBOSS, обратите внимание на журнал jboss.

JBoss автоматически создал запись JNDI для нашего сессионного компонента — LibraryPersistentBean / remote .

Мы будем использовать эту строку поиска для получения удаленного бизнес-объекта типа — com.tutorialspoint.stateless.LibraryPersistentBeanRemote

Вывод журнала сервера приложений 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 (клиент 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
  • Эти свойства используются для инициализации объекта InitialContext сервиса именования java.

  • Объект InitialContext будет использоваться для поиска сессионного компонента без сохранения состояния.

Эти свойства используются для инициализации объекта InitialContext сервиса именования java.

Объект InitialContext будет использоваться для поиска сессионного компонента без сохранения состояния.

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 выполняет следующие задачи —

  • Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

  • В методе testStatefulEjb () поиск jndi выполняется с именем — «LibraryStatelessSessionBean / remote» для получения удаленного бизнес-объекта (с сохранением состояния ejb).

  • Затем пользователю показывается пользовательский интерфейс магазина библиотеки, и ему / ей предлагается ввести выбор.

  • Если пользователь вводит 1, система запрашивает имя книги и сохраняет книгу, используя метод addBook () сессионного компонента без сохранения состояния. Сессионный компонент сохраняет книгу в базе данных с помощью вызова EntityManager.

  • Если пользователь вводит 2, система получает книги с использованием метода getBooks () сессионного компонента без сохранения состояния и завершает работу.

  • Затем выполняется другой поиск jndi с именем — «LibraryStatelessSessionBean / remote», чтобы снова получить удаленный бизнес-объект (EJB с сохранением состояния) и составить список книг.

Загрузите свойства из jndi.properties и инициализируйте объект InitialContext.

В методе testStatefulEjb () поиск jndi выполняется с именем — «LibraryStatelessSessionBean / remote» для получения удаленного бизнес-объекта (с сохранением состояния ejb).

Затем пользователю показывается пользовательский интерфейс магазина библиотеки, и ему / ей предлагается ввести выбор.

Если пользователь вводит 1, система запрашивает имя книги и сохраняет книгу, используя метод addBook () сессионного компонента без сохранения состояния. Сессионный компонент сохраняет книгу в базе данных с помощью вызова EntityManager.

Если пользователь вводит 2, система получает книги с использованием метода getBooks () сессионного компонента без сохранения состояния и завершает работу.

Затем выполняется другой поиск jndi с именем — «LibraryStatelessSessionBean / remote», чтобы снова получить удаленный бизнес-объект (EJB с сохранением состояния) и составить список книг.

Запустите клиент для доступа к EJB

Найдите EJBTester.java в проводнике проекта. Щелкните правой кнопкой мыши класс EJBTester и выберите файл запуска .

Проверьте следующий вывод в консоли 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)

EJB — обработка исключений

EJB-компоненты являются частью корпоративных приложений, которые обычно основаны на распределенных средах. Таким образом, помимо обычных исключений, которые могут возникнуть, могут быть исключения, такие как сбой связи, разрешения безопасности, отключение сервера и т. Д.

EJB-контейнер рассматривает исключения двумя способами:

  • Исключение приложения — если бизнес-правило нарушено или возникает исключение при выполнении бизнес-логики.

  • Системное исключение — Любое исключение, которое не вызвано бизнес-логикой или бизнес-кодом. RuntimeException, RemoteException являются SystemException. Например, ошибка во время поиска EJB. RuntimeException, RemoteException являются SystemException.

Исключение приложения — если бизнес-правило нарушено или возникает исключение при выполнении бизнес-логики.

Системное исключение — Любое исключение, которое не вызвано бизнес-логикой или бизнес-кодом. RuntimeException, RemoteException являются SystemException. Например, ошибка во время поиска EJB. RuntimeException, RemoteException являются SystemException.

Как EJB Container обрабатывает исключения?

Когда происходит исключение приложения , контейнер EJB перехватывает исключение, но возвращает его клиенту так же, как и он. Он не выполняет откат транзакции, если он не указан в коде методом EJBContext.setRollBackOnly (). EJB Container не переносит исключение в случае исключения приложения.

Когда возникает системное исключение , контейнер EJB перехватывает исключение, откатывает транзакцию и запускает задачи очистки. Он помещает исключение в RemoteException и отправляет его клиенту.

Обработка исключений приложения

Исключения приложений, как правило, вызываются в методах EJB Session, поскольку это методы, отвечающие за выполнение бизнес-логики. Исключение приложения должно быть объявлено в предложении throws бизнес-метода и должно быть выброшено в случае сбоя бизнес-логики.

@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;
   }
   ...
}

Исключение системы обработки

Системное исключение может произойти в любое время, например, если поиск имен не удался, при загрузке данных возникает ошибка sql. В таком случае такое исключение должно быть помещено в EJBException и возвращено клиенту.

@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;
   }
   ...
}

На стороне клиента обработайте исключение 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 — веб-сервисы

EJB 3.0 предоставляет возможность выставлять сеансовый EJB как веб-сервис. Аннотация @WebService используется для обозначения класса как конечной точки веб-службы, а @WebMethod — для представления метода в качестве веб-метода для клиента.

@Stateless
@WebService(serviceName="LibraryService")
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
	
   ...
   @WebMethod(operationName="getBooks")
   public List<Book> getBooks()  {    
      return entityManager.createQuery("From Books").getResultList();
   }
   ...
}

Пример приложения

Давайте создадим тестовое EJB-приложение для тестирования поддержки BLOB / Clob в EJB 3.0.

шаг Описание
1

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.entity, как описано в главе EJB — Создание приложения. Пожалуйста, используйте проект, созданный в главе EJB — Постоянство как таковой для этой главы, чтобы понять объекты clob / blob в концепциях EJB.

2

Создайте LibraryPersistentBean.java в пакете com.tutorialspoint.stateless. Используйте EJB — главу Постоянство в качестве ссылки. Сохраните остальные файлы без изменений.

3

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

4

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

Создайте проект с именем EjbComponent в пакете com.tutorialspoint.entity, как описано в главе EJB — Создание приложения. Пожалуйста, используйте проект, созданный в главе EJB — Постоянство как таковой для этой главы, чтобы понять объекты clob / blob в концепциях EJB.

Создайте LibraryPersistentBean.java в пакете com.tutorialspoint.stateless. Используйте EJB — главу Постоянство в качестве ссылки. Сохраните остальные файлы без изменений.

Очистите и создайте приложение, чтобы убедиться, что бизнес-логика работает в соответствии с требованиями.

Наконец, разверните приложение в виде файла JAR на сервере приложений JBoss. Сервер приложений JBoss запустится автоматически, если он еще не запущен.

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

Вывод журнала сервера приложений 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

Создание клиента для доступа к EJB в качестве веб-службы

В IDE NetBeans выберите « Файл»> «Новый проект»>. Выберите тип проекта в категории « Java» , «Тип проекта» в качестве приложения Java . Нажмите кнопку Далее>. Введите название проекта и местоположение. Нажмите Готово> кнопка. Мы выбрали имя как EJBWebServiceClient.

Щелкните правой кнопкой мыши на имени проекта в окне Project Explorer. Выберите « Создать»> «Клиент WebService» .

Клиент WSDL

Добавьте LibraryPersistentBean проекта компонента EJB, созданный ранее в WSDL и Расположение клиента, используя кнопку Добавить проект на вкладке компиляции .

Бин веб-службы

Нажмите кнопку Готово. Проверьте следующую структуру в проводнике проекта.

Бин веб-службы

Создать EJBWebServiceClient.java

package ejbwebserviceclient;

public class EJBWebServiceClient {
   public static void main(String[] args) {   
   }
}

Выберите веб-метод getBooks, как показано на рисунке ниже, и перетащите его в окно кода EJBWebServiceClient.

Перетаскивание метода веб-службы

Вы увидите вывод, аналогичный показанному ниже.

Метод веб-службы перетаскивается

Обновите код EJBWebServiceClient, чтобы использовать этот метод.

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

Запустите клиент

Щелкните правой кнопкой мыши на имени проекта в окне Project Explorer. Выберите Run . Netbeans соберет клиента и запустит его. Проверьте следующий вывод.

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)

EJB — Упаковочные приложения

Требования к пакетным приложениям, использующим EJB 3.0, аналогичны требованиям платформы J2EE. Компоненты EJB упакованы в модули в виде jar-файлов и упакованы в корпоративный архив приложения в виде файла ear.

Существует три основных компонента любого корпоративного приложения:

  • jar — Java-приложение aRchive, содержащее модули EJB, клиентские модули EJB и служебные модули.

  • war — веб-приложение aRchive, содержащее веб-модули.

  • ear — Enterprise Application aRchive, содержащий банки и модуль войны.

jar — Java-приложение aRchive, содержащее модули EJB, клиентские модули EJB и служебные модули.

war — веб-приложение aRchive, содержащее веб-модули.

ear — Enterprise Application aRchive, содержащий банки и модуль войны.

EAR

В NetBeans очень легко создавать, разрабатывать, упаковывать и развертывать приложения J2EE.

В IDE NetBeans выберите « Файл»> «Новый проект»> «. Выберите тип проекта в категории», « Java EE» , «Тип проекта в качестве корпоративного приложения» . Нажмите кнопку Далее> . Введите название проекта и местоположение. Нажмите Готово> кнопка. Мы выбрали имя EnterpriseApplicaton.

Выберите Сервер и Настройки. Установите флажки Create EJB Module и Create Web Application Module с указанными именами по умолчанию. Нажмите кнопку Готово. NetBeans создаст следующую структуру в окне проекта.

EAR Project

Щелкните правой кнопкой мыши Project Enterprise Application в проводнике проекта и выберите Build.

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)

Здесь вы можете видеть, что Netbeans сначала готовит Jar, затем War и, в конце концов, файл ear, содержащий файл jar and war. Каждый файл jar, war и ear содержит папку meta-inf для хранения метаданных в соответствии со спецификацией J2EE.