Главная » Java, Web » Компонент EJB-сущности

0

Серверные компоненты EJB для своей работы требуют наличия контейнера серверных компонентов EJB. Контейнером EJB, как правило, является часть сервера, поддерживающего работу с рядом технологий, в том числе работу с серверными компонентами EJB. В качестве примера возьмем сервер Blazix. Этот сервер содержит проводника создания серверных компонентов EJB. Проводник создания компонентов EJB позволит сконцентрироваться на основных принципиальных моментах, избавит от ненужных на первых шагах деталей. Общие принципы могут быть в дальнейшем использованы при работе и с другими серверами компонентов EJB. При работе с сервером Blazix необходимо убедиться в том, что переменная окружения path содержит путь к каталогу, в котором установлен сервер Blazix, а также в том, что в значении переменной classpath содержится файл blazixjar.

Еще раз напомним, из чего состоят компоненты EJB-сущности. требует наличия удаленного интерфейса. Этот интерфейс не производит непосредственно полезной работы, он служит для помощи клиенту, предоставляя ему ряд сервисов. Компонент EJB должен иметь домашний интерфейс. Перед тем как компонент EJB может быть использован, он должен быть найден или создан. Домашний интерфейс предоставляет методы для нахождения и создания компонентов EJB. также имеет уникальный первичный ключ.

Проводник создания серверных компонентов EJB для сервера Blazix носит название Blizzard. Приступим к созданию первого серверного компонента EJB. Создадим компонент EJB-сущности. Он будет работать с базой данных. Для этого понадобится простая таблица. Используем средства Microsoft Access и создадим таблицу, состоящую из двух столбцов. Первый столбец — key, второй — value, имеющий тип varchar (255) (рис. 5.5). Таблицу назовем nashaTabiitsa, базу данных назовем db.mdb.

Рис. 5.5. Создание базы данных

 

Рис. 5.6. Создание источника данных

Можно создать таблицу при помощи любой доступной базы данных. Для простоты воспользуемся MS Access. Создадим в Windows источник данных. Для этого откроем контрольную панель, найдем там пункт администрирования баз данных, закладку создания нового источника данных. Расположение этого сервиса может изменяться от одной системы к другой (рис. 5.6).

Выбираем драйвер для MS Access и переходим к следующему шагу. Задаем имя источника ODBC. Пусть это будет nashODBC (рис. 5.7).

Рис. 5.7. Задание имени источника данных

Переходим к следующему диалоговому окну, нажимая кнопку ОК. Здесь необходимо указать файл базы данных — это файл db.mdb (рис. 5.8).

Рис. 5.8. Задание файла базы данных

На следующем шаге не меняем ничего, закрываем настройки, нажав снова кнопку ОК (рис. 5.9).

Рис. 5.9. Имя источника данных задано

Переходим к конфигурированию компонентов EJB на сервере EJB. Необходимо внести созданный источник данных в файл ejb.ini. Это сделать несложно, нужно вставить в этот файл две строчки.

dataSource.name: nashiDannye

dataSource.nashiDannye.odbc: nashODBC

Затем вызовем проводник Blizzard. Появляется окно проводника создания компонента EJB. Выбираем создание серверного компонента EJB (рис. 5.10). В окне присутствует выпадающий список, с помощью которого можно выбрать базу данных, с которой будет работать компонент EJB. В данном случае это nashiDannye. Если источник данных доступен без указания имени пользователя пароля, то пропускаем этот шаг. Если имя и пароль требуются (они задаются во время создания источника данных или позже при изменении параметров источника данных), то указываем их и переходим к следующему шагу.

Текущая база данных содержит единственную таблицу, которая появится в окне проводника. Оставим ее в качестве той таблицы, с которой работает компонент EJB (рис. 5.11) и перейдем к следующему шагу. Проводник будет открывать отдельное окно для настройки каждого столбца в указанной таблице.

Рис. 5.10. Выбор источника данных для компонента EJB-сущности

 

Рис. 5.11. Выбор таблицы

Укажем, что столбец key будет использоваться как первичный ключ, поставив переключатель напротив пункта Use as the primary key. Тип значений данного столбца будет java.lang.string, что указывается в списке ниже (рис. 5.12).

Следующим столбцом в таблице будет столбец value. Он не будет использоваться в качестве ключа (рис. 5.13), но мы укажем, что для него генерируется специальная функция setter (установим переключатель в положение Generate Setter for this property). Задаем тот же тип значений, что и для предыдущего столбца, ТО есть java.lang.String.

Рис. 5.12. Задание параметров столбца key в таблице

 

Рис. 5.13. Задание значений параметров для столбца value

Переходим к последнему диалоговому окну проводника создания серверного компонента EJB. Здесь мы можем указать название компонента EJB и пакета. Здесь же указываем папку, в которой будут помещены файлы компонента EJB. Пусть это будет каталог c:\ejb (рис. 5.14). В качестве названия компонента EJB и пакета укажем NashBob и NashPaket соответственно.

После нажатия кнопки Build проводник генерирует необходимые файлы. Обычно это занимает несколько секунд или даже меньше. По завершении генерации в консоли проводника будет выведено сообщение о том, как происходит процесс создания файлов компонента EJB (рис. 5.15).

Рис. 5.14. Завершающий шаг работы с проводником по созданию серверного компонента EJB

 

Рис. 5.15. Сообщение о создании файлов компонента EJB

В папке c:\ejb находятся несколько сгенерированных файлов. Файл build.cmd содержит команды для компиляции классов. Код компонента EJB хранится в файлах NashBobHome.java (листинг 5.1), NashBobBean.java (листинг 5.2), NashBob.java (листинг 5.3). Помимо этого в папке META-INF расположен файл ejb-jar.xml.

Листинг 5.1. Файл NashBobHome.java

package NashPaket; impo rt j avax.ej b.*;

import java.rmi.*; import java.util.*;

public interface NashBobHome extends javax.ejb.EJBHome { NashBob create( java.lang.String key, java.lang.String value ) throws javax.ejb.CreateException, java.rmi.RemoteException;

NashBob findByPrimaryKey(java.lang.String pkey) throws j avax.ejb.EinderException, j ava.rmi.RemoteException;

Файл с описанием домашнего интерфейса достаточно прост. Класс самого компонента EJB тоже не очень сложен.

Листинг 5.2. Файл NashBobBean.java

package NashPaket; impo rt j avax.ej b.*; impo rt j avax.naming.*; import java.rmi.*;

public class NashBobBean implements javax.ejb.EntityBean { //Переменные

public java.lang.String key = null; public java.lang.String value = null; // Контекст (для работы с метками handles и пр.) javax.ejb.EntityContext ejbEntityContext = null; //Методы get/set

public java.lang.String getKeyO throws java.rmi.RemoteException { return key;

public java.lang.String getValue() throws java.rmi.RemoteException

return value;

public void setValue(java.lang.String value) throws java.rmi.RemoteException

this.value = value;

}

// Имплементация дополнительных удаленных методов.

// По умолчанию – метод ejbCreate.

public java.lang.String ejbCreate(

java.lang.String key,

java.lang.String value

)

throws javax.ejb.CreateException, java.rmi.RemoteException {

this.key = key; this, value = valued- return null;

}

// при необходимости имплементируются прочие дополнительные методы — // работа разработчика

public void setEntityContext(j avax.ej b.EntityContext ej bEnt ityContext) throws RemoteException {

this.ejbEntityContext = ejbEntityContext;

}

public void unsetEntityContext() throws RemoteException {

this.ejbEntityContext = null;

}

public void ejbPostCreate( java.lang.String key, java.lang.String value

)

{

// Создается разработчиком:

// функции, используемые после создания экземпляра компонента EJB. }

public void ejbRemoveO

throws java.rmi.RemoteException, j avax.ej b.RemoveException {

// Создается разработчиком:

// функции, выполняемые при уничтожении экземпляра компонента EJB. } public void ejbActivate() throws java.rmi.RemoteException

// Создается разработчиком:

// функции, используемые при активации экземпляра компонента EJB.

public void ejbPassivate() throws java.rmi.RemoteException

// Создается разработчиком:

// функции, выполняемые при пассивации компонента EJB.

public void ejbLoadO

throws java.rmi.RemoteException

// Создается разработчиком:

// загрузка прочих данных помимо тех, что предоставлены / / контейнером компонентов Е JB.

public void ejbStoreO

throws java.rmi.RemoteException

// Создается разработчиком:

// сохранение прочих данных, кроме тех, с которыми работает // контейнер компонента ЕJB.

Файл NashBob.java (листинг 5.3) по размеру небольшой.

Листинг 5.3. Файл NashBob.java

package NashPaket; impo rt j avax.ej b.*; import java.rmi.*;

public interface NashBob extends javax.ejb.EJBObject {

java.lang.String getKeyO throws java.rmi.RemoteException; java.lang.String getValue() throws java.rmi.RemoteException;

void setValue(java.lang.String value) throws java.rmi.RemoteException; // Создается разработчиком: // методы удаленного интерфейса.

Отметим, что во всех перечисленных файлах использован пакет для работы с серверными компонентами EJB javax.ejb.*, а также пакет для работы с вызовом удаленных процедур j ava. rmi. *.

Файл build.cmd (листинг 5.4) состоит из нескольких команд.

Листинг 5.4. Файл build.cmd

javac -d "c:\ejb" "c:\ejb\NashBobHome.java" "c:\ejb\NashBob.java" "с:\ejb\NashBobBean.java"

jar -cvf NashBob.jar -C "c:\ejb" META-INF/ejb-jar.xml "NashPaket/NashBobHome.class" "NashPaket/NashBob.class" "NashPaket/NashBobBean.class"

blxejbc NashBob.jar NashBobEjb.jar

Рис. 5.16. Создаем и упаковываем классы компонента EJB

В файле build.cmd содержатся три команды. Первая команда — это инструкция компиляции javac. Команда jar -cvf служит для создания файла JAR на основе полученных в результате выполнения предыдущей команды файлов классов. Наконец, blxejbc — это компилятор сервера Blazix для создания файла серверного компонента EJB, т. е. файла JAR, который готов к тому, чтобы быть размещенным на сервере. Для того чтобы команда blxejbc успешно выполнила все свои функции, необходимо в переменной path задать путь к папке, где установлен сервер Blazix.

Выполним (рис. 5.16) из консоли файл build.cmd (если javac не находит классы, убедитесь в том, что все необходимые пакеты установлены на вашем компьютере).

После компиляции в папке c:\ejb появится новая папка NashPacket, содержащая файлы трех классов, а также два новых файла в папке c:\ejb — файл NashBob.jar и файл NashBobEjb.jar.

Размещение компонента EJB на сервере

Для того чтобы разместить вновь созданный компонент EJB на сервере, необходимо изменить файл ejb.ini, вставив в него три строки.

Листинг 5.5. Вставка в файл ejb.ini

ejbJar: c:\ejb\NashBobEjb.jar еjb.NashBob.dataSource: nashiDannye ejb.NashBob.table: NashaTablitsa

Рис. 5.17. Сообщение о размещении компонента EJB на сервере

Теперь можно запустить сервер EJB. Если ошибки в конфигурировании серверных компонентов EJB не были допущены (файл ejb.ini содержит указанную выше информацию), то в консоли появится сообщение о том, что компонент EJB NashBob благополучно был размещен на сервере (рис. 5.17).

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

Обращение к серверному компоненту EJB

Удаленный интерфейс описан в файле NashBob.java. Удаленный интерфейс описывает методы взаимодействия с компонентом EJB-сущности. Прежде чем можно будет взаимодействовать с компонентом EJB, необходимо найти этот компонент EJB или же создать новый компонент EJB. Интерфейс, который позволяет обнаруживать или создавать новый компонент EJB, располагается в файле NashBobHome.java.

Сначала получаем ссылку на домашний объект следующим образом:

impo rt j avax.naming.*; impo rt j avax.ej b.*; import javax.rmi.*; import java.util.*; import props.* ;

Properties env = new Properties(); env.put("java.naming.factory.initial", "desisoft.ejb.client.JRMPFactory"); env.put("desisoft.ej b.nameServerl", "locaihost:2050");

Context ctx = new InitialContext(env); NashBobHome home = (NashBobHome) ctx.lookup("NashBob");

При работе с сервером Blazix, когда ссылка ищется из страниц JSP или из сервлета, передача свойств env конструктору InitialContext не требуется, поскольку окружение уже автоматически будет инициировано. Вместо этого нужно указать префикс поиска "java:comp/env/ejb/":

NashBobHome home = (NashBobHome) ctx.lookup("j ava:camp/env/ejb/Props"); Более корректный вариант последней строчки кода выглядит так, как показано ниже. Этот вариант портируем, так как в нем используется

PortableRemoteObj ect: Propshome home = (PropsHome)

PortableRemoteObject.narrow( ctx.lookup("NashBob"), NashBobHome.class);

Рекомендуется всегда при приведении типов использовать PortabieRemoteObject. Отметим, что каждый конкретный контейнер серверных компонентов EJB будет по-своему осуществлять поиск домашнего интерфейса. В данном случае сервер Blazix работает с классами

desisoft. е jb. *.

Теперь, когда мы располагаем ссылкой на домашний интерфейс, процесс нахождения или создания компонента EJB будет весьма прост: для этого нужно лишь вызвать соответствующий метод. После создания или нахождения компонента EJB мы получим удаленный интерфейс. Использование компонента EJB сводится к вызову методов этого удаленного интерфейса. Все вышесказанное можно реализовать при помощи кода, который приводится ниже (листинг 5.6).

Листинг 5.6. Файл клиента ClientBobSuschnosti.java

// пример обращения к компоненту EJB-сущности

impo гt j avax.naming.*;

impo rt j avax. e j b. *;

import javax.rmi.*;

import java.util.*;

import NashPaket.*;

public class ClientBobSuschnosti {

static public void main(String[] args)

checkArgs(args); try {

// получение домашнего интерфейса компонента EJB Properties env = new Properties(); env.put("java.naming.factory.initial", "desisoft.ejb.client.JRMPFactory"); env.put("desisoft.ej b.nameServerl", "localhost:2050") ;

Context ctx = new InitialContext(env);

NashBobHome home = (NashBobHome) PortabieRemoteObject.narrow (ctx.lookup("NashBob"), NashBob.class);

NashBob bean; if (doGet) { try {

bean = home.findByPrimaryKey(prop);

System.out.println(prop + ": " + bean.getValue());

}

catch (FinderException notFound) { System.out.println("Property V" + prop + was not found");

}

}

else { try {

bean = home.create(prop, value);

}

catch (DuplicateKeyException exists) { bean = home.findByPrimaryKey(prop);

}

bean.setValue(value);

System.out.printIn("Set value of + prop + to + value +

"V") ;

}

}

catch (Exception ex) { ex.printStackTrace();

}

}

static void usage() {

System.out.println("Usage: java ClientBobSuschnosti put <prop-name> <value>");

System.out.println(" java ClientBobSuschnosti get <prop-name>"); System.exit(0);

}

static void checkArgs(String[] args) {

if (args.length < 2)

usage(); prop = args[1];

if (args[0].equalsIgnoreCase("get")) {

if (args.length > 2)

usage(); doGet = true;

else

if (args[0].equalsIgnoreCase("put")) { if (args.length != 3) usage(); doGet = false;

value = args[2]; }

else

usage();

static boolean doGet = false; static String prop = null; static String value = null;

Этот код может быть использован только для jdkl.3, но не для jdkl.2. Для того чтобы скомпилировать этот код, необходимо указать в значении переменной class path файл NashBobEjb.jar. Поместим его в отдельную папку, где будут храниться приложения, пусть это будет папка c:\ejbtest, и скомпилируем, выполнив консольную команду javac ClientBobSuschnosti. java (рис. 5.18).

Рис. 5.18. Файл ClientBobSuschnosti.java скомпилирован

После компиляции появился класс ciientBobSuschnosti.class. Укажем путь к этому классу в качестве одного из путей, содержащихся в переменной CLASSPATH, а затем ВЫПОЛНИМ команду java CiientBobSuschnosti (рис. 5.19). Мы неправильно обратились к компоненту EJB, но в ответ получили инструкции, как следует к нему обращаться. Исправим ошибку, повторим обращение к компоненту EJB: Java CiientBobSuschnosti put imya znacheniye Получаем сообщения об ошибках (рис. 5.20).

Рис. 5.19. Синтаксическая ошибка при обращении к компоненту EJB

 

Рис. 5.20. Ошибка при обращении к компоненту EJB

Приведенные в качестве примера ошибки легко устранить — нужно запустить сервер компонентов EJB (сервер не был запущен). Запускаем сервер и повторяем команду

Java ClientBobSuschnosti put imya znacheniye

Опять получаем сообщения об ошибках (рис. 5.21). На этот раз получаем ошибку при обращении к базе данных.

Рис. 5.21. Ошибка при работе с базой данных

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

Java ClientBobSuschnosti put 101 777

Таким образом попытка завершилась удачно (рис. 5.22).

Рис. 5.22. Удачное обращение к компоненту EJB

Если сейчас попытаться существенно изменить структуру таблицы или базы данных, например, попытаться удалить таблицу, то система выдаст сообщение о том, что таблица используется (компонент EJB имеет постоянное подключение к таблице) и не может быть удалена. Выключим сервер компонентов EJB. Только сейчас таблицу можно модифицировать (например, удалить). Изменим таблицу: пусть значениями полей станут строки (рис. 5.23).

Рис. 5.23. Измененная таблица NashaTablitsa

 

Вновь запустим сервер компонентов EJB и выполним команду

Java ClientBobSuschnosti put imya znacheniye В этом случае не возникнет никаких проблем (рис. 5.24).

Рис. 5.24. Все неполадки устранены

Чтобы посмотреть значение параметра, выполняем команду (рис. 5.25).

Java ClientBobSuschnosti get imya

В примере, который рассматривался выше, компонент EJB находился по указанному значению первичного ключа. При этом всегда находится единственный компонент EJB, так как для данного первичного ключа существует лишь одна запись в базе данных. Существует и другой метод поиска компонента EJB. При этом в проводнике создания компонента EJB следует нажать кнопку Generate Finders (рис. 5.26).

Рис. 5.25. Получение значения параметра от компонента EJB

 

Рис. 5.26. Альтернативный метод поиска компонента EJB Следующий шаг — выбор критерия поиска (рис. 5.27).

Первый переключатель следует установить в том случае, если будут созданы компоненты EJB для всех значений столбца value, которые окажутся меньше, чем заданное значение. Второй переключатель соответствует выбору всех значений, больших, чем заданное. Третий переключатель соответствует созданию компонентов EJB при совпадении значения поля указанному значению. Последний четвертый переключатель соответствует поиску всех значений, расположенных между двух указанных значений. Выберем третий вариант и перейдем к завершающему шагу (рис. 5.28).

Рис. 5.27. Критерии поиска компонента EJB

 

Рис. 5.28. Задание имени компонента EJB и пакета

В качестве имени компонента EJB указываем NashBob2, пакет будет называться NashPaket2, каталог c:\ejb.

Новые методы поиска отражены в файле, содержащем домашний интерфейс (листинг 5.7).

Листинг 5.7. Файл NashBob2Home.java

package NashPaket2; impo rt j avax.ej b.*;

impo гt j ava.rmi.*; import java.util.*;

public interface NashBob2Home extends javax.ejb.EJBHome { NashBob2 create( java.lang.String key, java.lang.String value

)

throws j avax.ej b.CreateExcept ion, java.rmi.RemoteException;

NashBob2 findByPrimaryKey(java.lang.String pkey) throws j avax.ejb.FinderException, j ava.rmi.RemoteException;

java.util.Collection findValueEquals(java.lang.String value) throws

j avax.ejb.FinderException, j ava.rmi.RemoteException; }

Источник: Будилов В. А. Интернет-программирование на Java. — СПб.: БХВ-Петербург, 2003. — 704 е.: ил.

По теме:

  • Комментарии