Enterprise JavaBeans
Что такое EJB (Enterprise JavaBeans) и для чего она нужна? Можно ли обойтись без EJB при разработке WEB-приложений? Что даёт EJB программистам?
В java WEB-приложении можно использовать JSP (JavaServer Pages), JavaServer Faces (JSF), Struts, GWT. Для работы с базой данных можно использовать JDBC (Java Database Connectivity) или JPA (JBoss Hibernate). Применение в WEB-приложении servlet’a позволяет перехватить обращение к серверу и выполнить определенные действия, т.е. выполнить фильтрацию сообщений. Где и как в WEB-приложении можно использовать EJB?
Опыт показывает, что типовые задачи имеют типовые решения. Это и обеспечивает EJB, который представляет набор «фиксированных» решений типовых проблем, возникающих при разработке серверных приложений, а также проверенная временем схема реализации серверных компонентов. Эти фиксированные решения, или службы, предоставляются «контейнером EJB». Для доступа к этим службам необходимо создать специализированные компоненты, используя декларативные и программные EJB API, и развернуть их на сервере приложений.
Сервер приложений Java EE (Enterprise Edition) включает два основных компонента : WEB-container (для использования JSP, JSF, Struts и т.д.) и EJB-container. Первый компонент используется для создания пользовательского интерфейса и слабо подходит для описания бизнес-логики WEB-приложения. Для этого используется EJB-container.
Enterprise JavaBeans имеет спецификацию написания и поддержки серверных компонентов, содержащих бизнес-логику. Данная технология применяется, как правило, в том случае, если бизнес-логика требует один или несколько следующих сервисов :
- сервис распределённых транзакций;
- сервис сохранности данных (persistence);
- сервис управления данными;
- сервис событий;
- сервис именования и каталогов (JNDI);
- сервис безопасности и ограничения доступа к данным.
Технологию EJB можно рассматривать в двух аспектах: фреймворк и компонент. С точки зрения фреймворка EJB — это технология, предоставляющая для серверной части WEB-приложения множество готовых решений (управление транзакциями, безопасность, хранение информации и т.п.). С точки зрения компонента EJB — это надстройка над POJO-классом, описываемая с помощью аннотаций.
Основные типы компонентов EJB
В языке EJB под компонентом подразумевается зерно (Bean), а под Enterprise подразумевают «корпоративный». EJB делит компоненты (зерна) на несколько типов, исходя из их предназначения :
- сессионные (Session Beans), которые могут быть
- stateful — с сохранением текущего состояния;
- stateless — без сохранения состояния;
- singleton — один объект для всех приложений (начиная с EJB версии 3.1).
Сессионный компонент Session Beans, иначе называемый сеансовый, вызывается клиентом (браузером) для выполнения вполне определенных операций, таких как, к примеру, проверка кредитной истории клиента. Слово «сессионный» предполагает, что экземпляр компонента доступен только на время выполнения определенной задачи сервером, и безвозвратно уничтожается в случае аварии или остановки сервера. Для доступа к серверной части приложения, клиент вызывает методы сессионного компонента, выполняющего определенные бизнес-задачи внутри сервера.
Сеансовый компонент с сохранением состояния EJB stateful автоматически сохраняет свое состояние между обращениями к нему от одного и того же клиента, и завершает свое существование либо по таймауту, либо по явному запросу клиента. Типичным примером компонента с сохранением состояния является корзина с покупками в интернет-магазине.
Сеансовые компоненты без сохранения состояния EJB stateless не хранят никакой информации о своем состоянии и являются прикладными службами, которые выполняют все необходимые действия в рамках запроса. EJB stateless можно использовать для реализации таких операций, как перевод средств на кредитную карту или проверку кредитной истории клиента. На основе stateless-бинов проектируются WEB-сервисы.
Компоненты-одиночки EJB singleton используются совместно всеми клиентами, имеющими к ним доступ, и продолжают свое существование на протяжении всего времени работы приложения. Информацию о своем состоянии EJB singleton сохраняет. Компонент-одиночку можно использовать, к примеру, в интернет-магазине для реализации скидки, поскольку правила предоставления скидки фиксированы и распространяются на всех клиентов.
Сеансовые компоненты могут вызываться локально или удаленно, посредством Java RMI. Компоненты-одиночки и компоненты без сохранения состояния могут также экспортироваться в виде веб-служб SOAP (Simple Object Access Protocol) или REST (Representational State Transfer).
Компоненты управляемые сообщениями MDB (Message-Driven Bean) подобно сеансовым компонентам реализуют некоторую прикладную логику и имеют одно важное отличие: клиенты никогда не вызывают методы MDB напрямую. Вместо этого компоненты MDB вызываются для обработки отправленных на сервер сообщений, что позволяет организовать асинхронный обмен сообщениями между частями системы. Типичными примерами подобных серверов сообщений могут служить IBM WebSphere MQ, Oracle Advanced Queueing и TIBCO. Компоненты MDB, как правило, применяются для повышения надежности интеграции систем и асинхронной обработки данных. Примером MDB сообщения может быть запрос на доставку товарных запасов от автоматизированной системы розничной торговли к системе управления поставками.
Entity Bean и Java Persistence API
EJB тесно связан с двумя спецификациями : с JPA, которая является стандартом хранения данных для Java EE и с CDI (Contexts and Dependency Injection) которая обеспечивает возможность внедрения зависимостей и предоставляет службы управления контекстом для всех компонентов Java EE, включая EJB.
Возможность автоматического сохранения объектов в реляционной БД с использованием технологии объектно-реляционного маппинга (ORM) — так называемый механизм работы с persistence объектами, является одним из главных достоинств EJB. В контексте EJB persistence провайдер — это ORM-фреймворк, который поддерживает JPA, определяющий стандарт для :
- конфигурации маппинга Entity Bean и его отображения в БД;
- EntityManager API — стандартный API для CRUD (Create, Read, Update, Delete) операций над сущностями;
- Java Persistence Query Language (JPQL) — для поиска и получения данных приложения.
EntityManager API — это интерфейс, который связывает класс сущности приложения (Entity Bean) и её представления в БД. EntityManager знает как нужно добавлять сущности в БД, обновлять и удалять их, а также предоставляет механизмы для настройки производительности, кэширования, транзакций и т.д. Для этого используется язык запросов JPQL, очень похожий на SQL.
Контейнеры EJB-container
Java-приложениям для работы нужна виртуальная машина JVM (Java Virtual Machine). Сеансовым компонентам и компонентам MDB для работы точно также необходим контейнер EJB. Можно считать EJB-container развитием базовой идеи JVM. Так же, как JVM прозрачно управляет памятью, EJB-container обеспечивает компоненты EJB такими службами, как обработка транзакций, поддержка безопасности, удаленные взаимодействия и веб-службы.
Согласно спецификации EJB3 контейнер предоставляет службы, применимые только к сеансовым компонентам и MDB. Операция добавления компонента EJB3 в контейнер называется развертыванием (deployment). После того, как EJB-компонент благополучно развернут в контейнере, он готов к использованию приложениями.
В Java технологиях контейнеры не ограничены только EJB3. Контейнер Java EE – это сервер приложений с поддержкой EJB3, веб-контейнеров (сервлеты, JSP, JSF, Struts, GWT) и других Java EE API и служб. Примерами реализаций контейнеров Java EE могут служить следующие серверы приложений : Oracle WebLogic, GlassFish, IBM WebSphere, JBoss и Caucho Resin.
Определение наименования компонентов EJB
Формат именования компонентов EJB имеет следующий вид :
- workspace — пространство имен;
- app-name — наименование приложения;
- module-name — наименование модуля;
- ejb-name — наименование компонента;
- object-name — полное наименование объекта.
В представленном формате именования компонентов EJB ряд элементов (workspace, module-name, ejb-name) присутствуют в имени всегда и являются обязательными. А элементы [app-name] и [!object-name] могут отсутствовать и считаются необязательными.
workspace
Сервер Java EE может включать четыре пространства имен workspace, каждое из которых представляет свою область видимости.
java:comp Область видимости компонента. Все компоненты EJB из WAR-файла попадают в одно общее пространство имен java:comp. Скорее всего Вам редко придется пользоваться этим пространством имен, поскольку основное его предназначение – сохранение обратной совместимости с версиями Java EE 6 и ниже, где java:comp было единственным стандартным пространством имен. java:module Область видимости модуля. Все компоненты модуля попадут в одно пространство имен java:module. Для обратной совместимости java:comp и java:module интерпретируются в веб-модулях как одно пространство имен. Когда это возможно, вместо java:comp следует использовать java:module. java:app Область видимости приложения. Компоненты из всех модулей одного приложения размещаются в общем пространстве имен java:app. Примером приложения может служить архив EAR. Все WAR- и EJB-компоненты, развертываемые из EAR-архива попадают в это пространство имен. java:global Глобальное пространство имен. В java:global размещаются все компоненты из всех модулей и всех приложений. app-name
Значение наименования приложения [app-name] не является обязательным и присутствует только в именах тех компонентов EJB, которые развертываются на сервере приложений из EAR-архива. Если архив EAR не использовался, тогда [app-name] отсутствует в переносимых именах JNDI компонентов EJB. По умолчанию в качестве значения [app-name] выбирается имя EAR-файла без расширения .ear. Переопределить это умолчание можно в файле application.xml.
module-name
Значение module-name всегда присутствует в наименовании ресурса и является обязательным. Оно зависит от того, как развертываются модули, содержащие компоненты EJB. Если компоненты развертываются из отдельных файлов EJB-JAR (JAR-файлы развертываются непосредственно), в качестве значения module-name выбирается имя EJB-JAR файла без расширения .jar. Это умолчание можно переопределить с помощью элемента module-name в конфигурационном файле META-INF/ejb-jar.xml.
Если развертываются компоненты, являющиеся частью веб-модуля (WAR-файл), по умолчанию в качестве значения module-name выбирается имя WAR-файла без расширения .war. Это умолчание можно переопределить с помощью элемента module-name в конфигурационном файле WEB-INF/web.xml. Если развертываются компоненты, являющиеся частью приложения (EAR-файл), по умолчанию значение module-name определяется в зависимости от того, являются ли компоненты EJB частью EJB-JAR или WAR в EAR. При развертывании компонентов из WAR-файла, выбор значения module-name выполняется в соответствии с правилом для WEB-модулей, которое можно переопределить в дескрипторе WEB-INF/web.xml. При развертывании компонентов из файлов EJB-JAR, значением module-name становится полный путь к каталогу, где находится файл EJB-JAR внутри EAR, плюс имя файла EJB-JAR без расширения .jar, которое можно переопределить в файле META-INF/ejb-jar.xml.
ejb-name
Значение наименования компонента ejb-name является обязательным и всегда присутствует в наименовании ресурса. Для компонентов EJB, помеченных аннотациями @Stateless, @Stateful или @Singleton, в качестве значения ejb-name по умолчанию выбирается имя класса компонента. Это значение можно переопределить с помощью атрибута name() аннотации. Для компонентов EJB, объявленных в файле ejb-jar.xml, значение ejb-name определяется с помощью элемента bean-name.
object-name
Значение полного наименования объекта [!object-name] является обязательным, и переносимые имена компонентов EJB с этим элементом всегда будут присутствовать в JNDI. Но сервер EE также требует, чтобы в JNDI присутствовало имя без этого значения. Такое «усеченное» наименование может пригодиться, когда доступ к компоненту осуществляется через единственный интерфейс (или если компонент вообще не имеет интерфейса).
Новые статьи и уроки JAVA

JAVA EE:Разработка web-приложения. JPA. EJB. JSTL. Шестая статья серии, посвященной технологии JavaEE. Это одна из самых важных и интересных статей. В ней расказано о технологии JPA и EJB. Приведено теорическое описание этих технологий. На практике, в статье описывается процесс создания класса-сущностей из таблиц базы данных и вместе с ними создание сессионых компонентов. При работе с переменными классов сущностей в jsp страницам немного рассказывается о технологии JSTL, благодаря которой количество встраиваемого кода (скриплетов и пр.) в html разметке минимальна.
Важно заметить, что если все уроки из предыдущих статей можно было реализовать на веб-сервере Apache Tomcat, то начиная с этой статьи он более не способен удолетворить нуждам JavaEE (об этом говорится во второй статье), поэтому важно, чтобы у Вас был сервер приложений, поддреживающий технологию EJB.
1Веб-сервер Apache Tomcat не походит для реализации технологии EJB и JPA в JavaEE приложениях!
1Для реализации примеров из данной статьи понадобится снимок 4 урока. Забрать здесь.
Сведения о EJB и JPA
Enterprise JavaBeans — это высокоуровневая, базирующаяся на использовании компонентов технология создания распределенных приложений, которая использует низкоуровневый API для управления транзакциями. EJB существенно упрощает разработку, поставку и настройку систему уровня предприятия, написанных на языке Java.
Технология Enterprise JavaBeans определяет некоторый набор универсальных и предназначенных для многократного использования компонентов, которые называются Enterprise beans. При создании распределенных систем её бизнес-логика реализована на уровне этих Компонентов.
Компоненты EJB выполняются под управлением Сервера EJB, который выполняет роль связующего звена между Контейнерами и операционной средой. Сервер EJB обеспечивает доступ Контейнерам EJB к системным сервиса, таким, как управление доступом к базам данных или мониторам транзакций, а также к другим приложениям.
EJB контейнер предоставляет следующие сервисы:
- Lifecycle Management: Индивидуальные ентерпрайс бины не нуждаются в явном управлении процессом, управлении потоками, активации объектов или их разрушении. EJB контейнер автоматически управляет жизненным циклом объекта.
- State Management: Индивидуальные ентерпрайс бины не нуждаются в явном сохранении или восстановлении состояния объекта между вызовами методов. EJB контейнер автоматически управляет состоянием объекта.
- Security: Индивидуальные бины не нуждаются в явной аутентификации пользователей или проверке авторизационных уровней. EJB контейнер автоматически производит все проверки безопасности.
- Transactions: Бин не обязан явно определять код транзакций для участия в распределенных транзакциях. EJB контейнер может автоматически управлять стартом, откатом, записью транзакций по требованию бина.
- Persistence: EJB контейнер автоматически управляет сохранением данных.
Session компоненты
Session компонент представляет собой объект, созданный для обслуживания запросов одного клиента. В ответ на удаленный запрос клиента, Контейнер создает экземпляр Компонента. Session-компонент всегда сопоставлен с одним клиентом; можно рассматривать его как представителя клиента на стороне EJB-сервера. Такие Компоненты могут «знать» о наличии транзакций — они могут отвечать за изменение информации в базах данных, но сами они непосредственно не связаны с представлением данных в БД.
Session-компоненты являются временными объектами и существуют сравнительно недолго. Обычно Session-компонент существует, пока создавший его клиент поддерживает с ним «сеанс связи». После завершения связи с клиентом компонент уже никак не сопоставлен с ним. Объект читается временным, так как в случае завершения работы (или «падения») сервера клиент должен будет создать новый Компонент.
Обычно Session-компонент содержит параметры, которые характеризуют состояние его взаимодействия с клиентом, т.е. он сохраняет некоторое состояние между вызовами удаленных методов в процессе сеанса связи с клиентом. Session-компоненты, которые поддерживают состояние, называются stateful-компонентами. Состояние существует, пока существует сеанс взаимодействия с клиентом.
Session-компонент может также не иметь состояния (stateless-компонент). Он не хранит характеристик своего взаимодействия с клиентом. Когда клиент вызывает один из его методов, разумеется, происходит изменение значений некоторых внутренних переменных, но эти значения имеют смысл только во время обработки этого единственного вызова — до его завершения. Таким образом, все экземпляры одного stateless-компонента являются идентичными (кроме интервалов времени, когда выполняется код одного из методов). Вследствие этого ничто не мешает одному и тому же экземпляру компонента обслуживать вызовы различных клиентов. Контейнер EJB может создать пул экземпляров таких Компонентов и выбирать любой из них для обслуживания клиентских запросов.
Entity-компоненты
Entity-компоненты представляют собой объектное представление данных из БД. Например, Entity-компонент может моделировать одну запись из таблицы реляционной базы данных. Несколько клиентов могут одновременно обращаться к одному экземпляру такого Компонента. Entity-компоненты изменяют состояние сопоставленных с ними баз данных в контексте транзакций.
Состояние Entity-компонентов в общем случае нужно сохранять, и «живут» они столько, сколько существуют в базе данных те данные, которые они представляют, а не столько, сколько существуют клиентский или серверный процессы. Остановка или «падение» Контейнера EJB не приводит к уничтожению содержащихся в нем Entity-компонентов.
За сохранность компонента может отвечать сам Компонент (Bean Managed Persistence, BMP) или его Контейнер (Container Managed Persistence, CMP). При использовании CMP все обязанности по сохранению состояния Компонента возлагаются на Контейнер. В случае BMP, Вы должны написать для Компонента нужный код, включая обращение к базам данных.
Каждый Entity-компонент характеризуется своим уникальным идентификатором — primary key. Обычно это тот же самый primary key, что и идентификатор данных в БД, например, совокупность ключевых полей записи в таблице.
Инфраструктура EJB
На рисунке ниже показаны различные элементы инфраструктуры EJB. Она должна обеспечивать канал связи с клиентом и другими Компонентами EJB. Хотя спецификация этого не требует, желательно, чтобы этот канал обеспечивал безопасность передаваемых данных, особенно при работе в Internet. Инфраструктура должна также обеспечивать соблюдение прав доступа к компонентам EJB.

JPA – это технология, обеспечивающая объектно-реляционное отображение простых JAVA объектов и предоставляющая API для сохранения, получения и управления такими объектами.
JPA – это спецификация (документ, утвержденный как стандарт, описывающий все аспекты технологии), часть EJB3 спецификации.
Сам JPA не умеет ни сохранять, ни управлять объектами, JPA только определяет правила игры: как что-то будет действовать. JPA также определяет интерфейсы, которые должны будут быть реализованы провайдерами. Плюс к этому JPA определяет правила о том, как должны описываться метаданные отображения и о том, как должны работать провайдеры. Дальше, каждый провайдер, реализуя JPA определяет получение, сохранение и управление объектами. У каждого провайдера реализация разная.
Преимущества использования JPA:
- Для выполнения статических и динамических запросов в JPA используется собственный язык запросов, схожий с SQL. При использовании языка запросов Java Persistence Query Language (JPQL) приложения можно переносить между базами данных различных поставщиков.
- Можно избежать написания низкоуровневого кода JDBC/SQL.
- JPA предоставляет прозрачные службы для кэширования данных и оптимизации производительности.
Если Вы впервые сталкиваетесь с этой технологией, то Вам может показаться все сложным и запутанным, но все станет намного понятнее после реализации примера на практике.
1Не отступать и не бояться!
Создание классов сущностей
А теперь будет только интересное и захватывающее. Начнем с созданием классов сущностей (Entity-classes). Средствами IDE NetBeans это делается очень легко.
- Откройте проект myblog.
- Нажмите на кнопку создания нового файла . В списке категорий выберите «Персистентность» (или «Сохраняемость«, зависет от версии IDE).
- В сформировавшемся списке Типов Файлов выберите «Классы сущностей из базы данных«.
IDE создало 4 файла сущностей и один файл настроек persistence.xml.
Теперь на примере класса Articles (откройте его в окне редактора) разберемся как формируется entity-класс.
В самом верху мы видим следующий код:
Аннотация @Entity указывает на то что этот класс есть сущность.
@Table(name=»tableName») — указывается имя таблицы из БД с которой связан класс
@XmlRootElement — просто говорит о том что значения класса представляются как XML элементы в документе XML. Необязательный параметр.
Если присмотреться, то вы заметите подобие SQL запросов в тексте, это не случайно. На самом деле это способ, который позволяет нам писать на EJB-QL аналога SQL для EJB. При написание названий полей мы обращаемся не к полям БД, а к переменным классам, поэтому важно, чтобы они совпадали по названию именно с переменными.
@Id — сообщает о том, что данное поле является идентификатором.
@GeneratedValue(strategy=GenerationType.IDENTITY) — сообщает, что значение поля будет генерироваться автоматически, а strategy=GenerationType.IDENTITY указывает на то, что этим вопросом будет заниматься сама БД.
@Basic — говорит о том, что поле будет сохраняться в БД, но мы то понимаем, что оно будет это делать в любом случае. Совсем не обязательное поле.
@Column(name=»id») — думаю тут понятно, указывается название поля в БД с которым ассоциируется значение.
Ну и после всех аннотация приводится сама переменная.
Подобный образом описаны все поля БД. После них идет кое-что еще более интересное:
Это ответ на вопрос «почему не создана сущность для таблицы grouppuser_has_articles«. В аннотации мы описываем связь каждой из участвующих таблиц с таблицей grouppuser_has_articles.
@ManyToMany — указываем, что имеет место связь многим-ко-многим. И объявляем Коллекцию типа Groupuser. Теперь, имея переменную типа Articles, мы просто будем обращаться к значению переменой groupuserCollection чтобы получить список всех групп, которые привязаны к данной статье. Это делается прозрачно для нас, разработчиков, минуя таблицу grouppuser_has_articles. Удобно до жути.
Здесь уже понятнее, аннотацией @OneToMany мы объявляем связь один-ко-многим
Свойство CascadeType.ALL (а также INSTERT, UPDATE, DELETE, ALL включает в себя все три вида каскада). Это означает каскадное обновление записей в базе данных.
Далее идут конструкторы, гетеры и сетеры для значений переменных класса.
Теперь откройте файл persistance.xml. На вкладке «Конструктор» показаны свойства данной единицы персистентности. Запомним что ее название «myblogPU«, далее пригодится. Также обозначен провайдер персистентности и источник данных. Из следующих свойств нам наиболее интересен «Режим общего кэша«. Дело в том, что при работе с сущностями, EJB хранит их значение в кэше, и при очередном обращение к содержимому переменных, он не будет каждый раз обращаться к базе данных за новым значением, а просто будет брать его из кэша. Вполне очевидно потенциальная проблема, когда в базе данные изменились, а в кэше еще нет. О вариантах ее решения мы поговорим в следующих статьях.
Создание сессионных компонентов
Пришло время создать фасад сеанса.
Фасад сеанса — это шаблон проектирования. Как указано в документе Core J2EE Pattern Catalog, этот компонент пытается решить общие проблемы, возникающие в многопоточном приложении, например:
- Жесткие связи, приводящие к прямой зависимости между клиентскими и бизнес-объектами.
- Излишние вызовы методов между клиентом и сервером, приводящие к проблемам производительности сети.
- Недостаточная общность стратегий доступа клиентов, что вызывает недопустимое использование бизнес-объектов.
Фасад сеанса маскирует взаимодействие основных бизнес-объектов и создает уровень служб, предоставляющий только необходимые функциональные возможности. Это позволяет скрыть от клиента сложную схему взаимодействия участников. Таким образом, сеансовый компонент (т.е. фасад сеанса) управляет взаимодействием бизнес-объектов. Сеансовый компонент также управляет жизненным циклом участников, создавая, находя, редактируя и удаляя их в соответствии с рабочим процессом.
-
Откройте меню создания нового файла, в столбце категорий выберите вновь «Персистентности«, а в столбце типов файлов выберите «Сеансовые компоненты для сущностных классов«.
Теперь в пакете session появилось 5 новых классов. Почему 5 а не 4? IDE создало AbstractFacade как абстрактный класс, заготовка для всех остальных. Откройте любой другой сессионный класс, Вы увидите что он наследуется от AbstractFacade.
Откроем один из классов фасада и посмотрим что внутри.
В самом начале идет аннотация
Как мы уже говорили ранее, это говорит о том что сессионый компонент без сохранения состояния.
Аннотация @PersistenceContext используется для добавления в класс интерфейса EntityManager, управляемого контейнером. Другими словами, контейнер EJB проекта GlassFish используется для открытия и закрытия интерфейсов EntityManager, когда это необходимо. Элемент unitName указывает блок сохранения состояния myblogPU, который был определен в файле persistence.xml приложения.
EntityManager (диспетчер сущностей) — внутренний компонент интерфейса API сохранения состояния Java, отвечающий за сохранение состояния в базе данных. В книге EJB 3 в действии EntityManager описан следующим образом:
В нашем проекте имеется теперь модель состояния базы данных в виде класса сущностей и имеются сессионные компоненты (фасады) для доступа к классам сущностей.
Получение данных через EJB
Пришло время испытать наше творение и отобразить что-нибудь из базы данных на странице в браузере. Первое, что нам можно сделать, это отобразить список статей на главной странице сайта.
Сделаем предположение что список статей не будет меняться чаще чем ± 1 раз в сутки. Это значит, что было бы не плохо раз загрузить эти данные в память и не гоняться за ними каждый раз в базу данных при новом обращение к главной странице.
- Откройте наш web_controller.java (сервлет).
- Сразу после объявления класса объявим новый EJB компонент.
Аннотация @EJB говорит о том что ниже объявлен EJB компонент, в нашем случае ArticlesFacade. - Далее нам необходимо добавить функцию init(). Эта функция инициализация сервлета, выполняется только один раз, при старте сервлета. Можно написать ее ручками. В качестве ознакомления мы воспользуемся средствами IDE для генерации кода.
Нажмите правой кнопкой мыши по пустой строке после объявления EJB компонента, в появившемся контекстном меню выберите пункт «Вставка кода. «.
1Важно заметить что если приложение является распределенным и имеет соотвествующею пометку в дескриптере развертывания «distributed», то контекст создается по одному на каждую виртуальную машину. В этом случае его нельзя использовать как носитель глобальной информации. Для этого подойдет база данных.
Для ознакомления приведу список возможных контекстов:
Контекст Описание контекста pageScope Контекст страницы (все переменые доступны только внутри страницы в которой были объявлены). requestScope Доступ к таким переменным имеют все страницы, сервлеты обслуживающие один, текущий, вот этот самый, запрос пользователя. sessionScope Доступ к переменным доступен отовсюду и сохраняются только для текущего сеанса пользователя, до тех пора пока сеанс не прекращен. applicationScope Доступ к переменным сохраняется изо всех страниц, размещенных внутри веб-приложения (самый глобальный контекст). param В этом контексте находятся все переменные, полученные страницей от пользователя GET или POST запросом. paramValues Список значений тех переменных, которые были получены от пользователя GET или POST запросом, правда, формат отличен от предыдущего случая. Если там param фактически имел тип HashMap<String, String>, то здесь HashMap<String, String [] >. header В этом объекте хранится информация об http-заголовках, которые были переданы от браузера клиента вашему веб-серверу. headerValues Список значений http-заголовков. initParam Конфигурационные параметры, указанные в файле web.xml cookie Список переменных, помещенных внутрь cookie. Вернемся к нашему контексту, в него методом setAttribute мы поместили список всех наших статей. В первом параметры мы указали имя атрибута «articles», во втором получили сами значения, используя метод findAll() у объявленного нами ранее фасада класса Articles. Данный метод вернул нам объект типа List.
После того, как мы получили список статей и погрузили их в глобальный контекст, необходимо получить их в jsp странице и вывести пользователю.
- Откройте в редакторе файл header.jspf и в самом верху страницы добавьте следующие строки:
- Этой строкой мы объявили библиотеки тегов.
JSTL — J ava S tandard T ag L ibrary или другими словами — стандартная библиотека тегов. Она представляет из себя библиотеку тегов, которые инкапсулируют базовый функционал, необходимый для написания динамических JSP страниц. JSTL была создана для того, чтобы позволить JSP программистам писать с использованием тегов, вместо того, чтобы встраивать java код в скриплеты.
Объявленный первым тэг является так называемым Сore Tag Library, и содержит в себе методы циклов, выполнений условий, базовый ввод-вывод. Также имеется другие библиотеки, о них поговорим в следующей статье. Второй тэг объявляет библиотеку которая содержит всевозможные функции для работы с переменными.
1Если по какой-то причине веб-сервер не понимает jstl тэги, необходимо скачать библиотеку тегов с сайта glassfish и поместить в ее в директорию lib в папке сервера. После этого перезапустить сервер.
Если сейчас развернуть приложение, то результатов на главной странице мы не увидим. Все потому, что сейчас сервлет не загружен т.к. к нему не было ни одного обращения. Чтобы сервлет грузился сразу при старте приложения, добавьте следующий код в аннотацию web_controller’а.
Теперь мы увидим результат нашей работы.

Все хорошо, за исключением того, что дата выводится не в самом удобном виде. Как мы уже знаем, все обращения к значениям из класса сущности осуществляются не явно через гетеры. Откроем в редакторе файл Articles.java.
- Найдите функцию
- Замените эту функцию на следующию:
- Обновите страницу. Теперь дата отображается в привычном виде.

1 Снимок готового урока можно забрать на GitHub.
Это был один из самых важных уроков. Во время его прохождения наверняка возникнут ошибки и вопросы, однако, если Вы сможете их решить и разобраться во всех вопросах, то дальнейшее изучение технологии JavaEE дастся намного легче. Вопросы также можно оставлять в комментариях, автор с удовольствием на них ответит.
В следующем уроке будет подробно рассмотрена технология JSTL, показан метод получения информации от пользователя и ее обработка.
Введение в основы EJB3
Так как я уже затрагивал тему EJB3 в уроках, то решил рассмотреть его более детальней.
Немного о EJB
EJB (Enterprise Java Beans) – это фреймворк для построение бизнес-логики приложения.
Сервер приложений J2EE состоит из двух основных элементов:
WEB-Container – (JSP, JSF и т.д.) все что дает конечный вид пользователю, а точней пользовательский интерфейс.
EJB-Container – используется для написания бизнес-логики.
С точки зрения EJB – это технология, предоставляющая множество готовых решений (управление транзакциями, безопасность, хранение информации и т.п.) для вашего приложения.
EJB делится на три типа компонентов
1. Session beans – используется для построения бизнес-логики, которая может быть вызвана программным клиентом через локальный, удаленный или веб-интерфейс обслуживания клиентов.
Для доступа к приложению, развернутого на сервере, клиент вызывает методы сессионного компонента. Сессионный компонент выполняет работу для своего клиента, защищая его от сложности, выполняя бизнес-задач внутри сервера.
Существует 2 типа session-beans: stateless и stateful.
Stateful – автоматически сохраняют свое состояние между разными клиентскими вызовами.
Stateless – используются для реализации бизнесс-процессов, которые могут быть завершены за одну операцию.
2. Message-Driven beans – компонент является корпоративным компонентом, который позволяет Java EE приложениям обрабатывать сообщения асинхронно.
Этот тип бинов обычно действует в качестве слушателя JMS-сообщения, который похож на слушателя событий, но получает JMS-сообщений вместо событий. Сообщения могут быть отправлены на любой компонент Java EE (клиентское приложение, другой компонент, или веб-компонент) или JMS приложение или систему, которая не использует Java EE технологий.
Message-Driven beans может обрабатывать не только JMS сообщения но и других видов сообщений.
На схеме выше можно наблюдать общение между приложением и сервером с помощью очереди куда поступают сообщения.
3. Entities – это сущности каких то объектов и в EJB оно является хранилищем данных на период жизненного цикла Entity.
Entities является свое-родным отображением таблиц в БД.
Одним из главным достоинством EJB3 стал новый механизм работы с persistence, он дает возможность автоматически сохранять объекты в реляционной БД используя технологию ORM.
Для работы с entity был создан JPA (Java Persistence API).
JPA определяет стандарт для:
1) конфигурации маппинга сущностей приложения и их отображения в таблицах БД;
2) EntityManager API – позволяет выполнять CRUD (create, read, update, delete) операции над сущностями;
3) Java Persistence Query Language (JPQL) – для поиска и получения данных приложения;
Основные аннотации EJB3
@EJB – помечается bean, который мы собираемся использовать.
@Stateless – говорит контейнеру, что класс будет stateless session bean. Для него контейнер обеспечит безопасность потоков и менеджмент транзакций.
@Local – относится к интерфейсу и говорит, что bean реализующий интерфейс доступен локально.
@Remote – относится к интерфейсу и говорит, что bean доступен через RMI (Remote Method Invocation).
@Stateful – говорит контейнеру, что класс будет stateful session bean.
@Remove – метод, помеченный как Remove говорит контейнеру, что после его исполнения нет больше смысла хранить bean, т.е. его состояние сбрасывается. Это бывает критично для производительности.
@Entity – говорит контейнеру, что класс будет сущностью БД.
@Table(name=”<name>”) – указывает таблицу для маппинга БД.
@Id – указывает уникальный идентификатор сущности который будет ключом в БД.
@Column – указывает параметры колонки в БД включая имя колонки в БД.
@WebService – говорит, что интерфейс или класс будет представлять web-сервис.
Правила создания session bean
В качестве session bean может выступать обычный класс Java, но он должен удовлетворять следующим условиям:
1. Он должен иметь как минимум один метод;
2. Он не должен быть абстрактным;
3. Он должен иметь конструктор по-умолчанию;
4. Методы не должны начинаться с “ejb” (например ejbBean, ejbGoAtHome)
5. Свойства класса должны быть объявлены примитивами или реализовывать интерфейс Serializable.
Жизненный цикл EJB3
У stateless и MDB бинов существует 2 события жизненного цикла, которые мы можем перехватить. Это создание и удаление бина.
Метод, который будет вызываться сразу после создании бина помечается аннотацией @PostConstruct, а перед его удалением – @PreDestroy.
Stateful бины обладают помимо рассмотреных выше еще 2 событиями: