Java на сервере
Тенденция написания сетевых программ – побольше функций возложить на серверную часть программы и поменьше оставить клиентской части, сделав клиент "тонким", а сервер "толстым". Это позволяет, с одной стороны, использовать клиентскую часть программы на самых старых и маломощных компьютерах, а с другой стороны, облегчает модификацию программы – все изменения достаточно сделать только в одном месте, на сервере.
Сервер выполняет все больше функций, как говорят, служб или сервисов (services). Он и отправляет клиенту Web-страницы, и выполняет сервлеты, и связывается с базой данных, и обеспечивает транзакции. Такой многофункциональный сервер называется сервером приложений (application server). Большой популярностью сейчас пользуются серверы приложений WebLogic фирмы ВЕА Systems, IAS (Inprise Application Server) фирмы Borland, WebSphere фирмы IBM, OAS (Oracle Application Server). Важной характеристикой сервера приложений является способность расширять свои возможности путем включения новых модулей. Это удобно делать с помощью компонентов.
Фирма SUN Microsystems предложила свою систему компонентов EJB (Enterprise JavaBeans), включенную в Java 2 SDK Enterprise Edition. Подобно тому, как графические компоненты JavaBeans реализуют графический интерфейс пользователя, размещаясь в графических контейнерах, компоненты EJB реализуют различные службы на сервере, располагаясь в EJB-контейнерах. Этими контейнерами управляет EJB-сервер, включаемый в состав сервера приложений. В составе J2SDKEE EJB-сервер – это программа j2ee. Серверу приложений достаточно запустить эту программу, чтобы использовать компоненты EJB.
В отличие от JavaBeans у компонентов EJB не может быть графического интерфейса и ввода с клавиатуры. У них может отсутствовать даже консольный вывод. Контейнер EJB занимается не размещением компонентов, а созданием и удалением их объектов, связью с клиентами и другими компонентами, проверкой прав доступа и обеспечением транзакций.
Программы, оформляемые как EJB, могут быть двух типов: EntityBean и sessionBean. Они реализуют соответствующие интерфейсы из пакета javax.ejb. Первый тип EJB-компонентов удобен для создания программ, обращающихся к базам данных и выполняющих сложную обработку полученной информации. Компоненты этого типа могут работать сразу с несколькими клиентами. Второй тип EJB-компонентов более удобен для организации взаимодействия с клиентом. Компоненты этого типа бывают двух видов: сохраняющие свое состояние от запроса к запросу (stateful) и теряющие это состояние (stateless). Методами интерфейсов EntityBean и SessionBean контейнер EJB управляет поведением экземпляров класса. Если достаточно стандартного управления, то можно сделать пустую реализацию этих методов.
Кроме класса, реализующего интерфейс EntityBean или SessionBean, для создания компонента EJB необходимо создать еще два интерфейса, расширяющие интерфейсы EJBhome и EJBObject. Первый интерфейс (home interface) служит для создания объекта EJB своими методами create (), для поиска и связи с этим объектом в процессе работы, и удаления его методом remove (). Второй интерфейс (remote interface) описывает методы компонента EJB. Интересная особенность технологии EJB – клиентская программа не образует объекты компонента EJB. Вместо этого она создает объекты home- и remote-интерфейсов и работает с этими объектами. Реализация home- и remote-интерфейсов, создание объектов компонента EJB и взаимодействие с ними остается на долю контейнера EJB.
Приведем простейший пример. Пусть мы решили обработать выборку из базы данных, занесенную в объект rs в сервлете листинга П.3, с помощью компонента EJB. Для простоты пусть обработка заключается в слиянии двух столбцов методом merge (). Напишем программу:
import java.rmi.RemoteException; import javax.ejb.*; public class MergeBean implements SessionBean{ public String merge(String si, String s2){ String s = si + " " + s2; return s; } // Выполняется при обращении к методу create() // интерфейса MergeHome. Играет роль конструктора класса public void ejbCreate() {} // Пустая реализация методов интерфейса public void setSessionContext(SessionContext ctx){} public void ejbRemoveO {} public void ejbActivate()(} public void ejbPassivate(){} } public interface MergeHome extends EJBHome{ // Реализуется методом ejbCreate() класса MergeBean Merge create)} throws CreateException, RemoteException; } public interface Merge extends EJBObject{ public double merge(String si, String s2) throws RemoteException; }