Учебный курс по электронной коммерции NetBeans. Добавление классов сущностей и сеансных компонентов

Содержимое на этой странице применимо к IDE NetBeans, версии 6.8 и 6.9

В этом учебном курсе рассмотрены технологии Enterprise JavaBeans (EJB) и Java Persistence (JPA). Используются необходимые для разработки в Java EE мастеры среды IDE. Это:

  • Мастер создания классов сущностей из базы данныхДля каждой выбранной таблицы базы данных создается класс сущности, сохраняющий состояние при помощи JPA, с аннотациями именованных запросов, полями, соответствующими столбцам и отношениями, соответствующими внешним ключам.
  • Мастер сеансных компонентов для классов сущностейСоздает фасад сеанса EJB для каждого класса сущностей с основными методами доступа.

Эти два мастера предоставляют эффективный способ быстрого создания модели для приложения. При рассмотрении диаграммы MVC для создаваемого приложения можно увидеть место расположения сеансных компонентов EJB и классов сущностей JPA в его структуре.

Диаграмма MVC приложения AffableBean

Создаваемые в этом разделе классы сущностей создают представление базы данных affablebean в форме Java. Каждый класс сущностей представляет таблицу базы данных, а экземпляры классов сущностей соответствуют записям, сохраняемым в базе данных. Бизнес-логика приложения инкапсулируется сеансными компонентами, которые могут использоваться как классы фасада, предоставляющие доступ CRUD (создание, чтение, обновление, удаление) к записям (см. ниже), или могут содержать код, реализующий характерные для приложения действия. Пример такого использования приведен в разделе Раздел 9: интеграция транзакционной бизнес-логики.

Можно просмотреть интерактивную демонстрацию приложения, которое создается в этом учебном курсе: Демонстрация приложения электронной коммерции NetBeans



Программное обеспечение или материал Требуемая версия
IDE NetBeans Набор Java, версия 6.8 или 6.9
Комплект для разработчика на языке Java (JDK) версия 6
Сервер GlassFish v3 или Open Source Edition 3.0.1
Сервер базы данных MySQL Версия 5.1
Проект AffableBean снимок 3

Примечания:

  • The IDE NetBeans requires the Java Development Kit (JDK) to run properly. Если указанные материалы не установлены, JDK следует загрузить и установить в первую очередь.
  • The IDE NetBeans Java Bundle includes Java Web and EE technologies, which are required for the application you build in this tutorial.
  • The IDE NetBeans Java Bundle also includes the GlassFish server, which you require for this tutorial. Можно загрузить сервер GlassFish отдельно, но версия, предоставляемая с NetBeans, имеет преимущество, так как автоматически зарегистрирована в среде IDE.
  • Этот учебный курс можно выполнять без выполнения предыдущих. Для этого обратитесь к инструкциям по настройке, в которых описана подготовка базы данных и настройка подключений между IDE, GlassFish, и MySQL.
  • Snapshot 4 of the AffableBean project is available for download and corresponds to state the project after completing this unit using IDE NetBeans 6.9.

Общие сведения о технологиях EJB и JPA

До сих пор проект, который создавался в процессе этого учебного курса, можно было запустить на веб-сервере с контейнером сервлетов, таком как Apache Tomcat. Пока использовались только технологии JSTL и сервлетов, а подключение к базе осуществлялось напрямую через JDBC. Теоретически можно продолжать разработку с применением только этих технологий и вручную писать код для всех аспектов приложения, включая многопоточное исполнение, транзакции и безопасность. Однако компоненты EJB и классы сущностей JPA позволяют сосредоточиться на бизнес-логике приложения, используя проверенные и протестированные решения. В следующих разделах рассматриваются данные технологии и их роль в разработке для Java EE.

JavaBeans Enterprise

На официальной странице продукта EJB технология EnterPrise JavaBeans описана как "компонентная архитектура клиент-сервер", которая "позволяет быстро и легко разрабатывать распределенные транзакционные безопасные и переносимые приложения." При применении EJB все службы, предоставляемые этой технологией, остаются прозрачными для разработчика, избавляя его от утомительного и часто приводящего к ошибкам добавления кода заготовок. Для новичка в разработке для Java EE потребность в EJB для веб-приложения Java неочевидна. В книге Дебу Панды, Реза Рахмана и Дерека Лейна (Debu Panda, Reza Rahman и Derek Lane) EJB 3 в действии (EJB 3 In Action) роль EJB четко сформулирована:

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

Контейнер EJB предоставляет эти функциональные возможности в виде встроенных, поэтому компоненты EJB могут использовать их в приложении. Это освобождает разработчика от необходимости изобретать велосипед. Например, при написании модуля обработки кредитных карт в веб-приложении необходимо создать большой объем сложного и приводящего к ошибкам кода для управления транзакциями и контроля безопасности доступа. Можно избежать этого, используя декларативные транзакции и службы безопасности контейнера EJB. Эти службы доступны компонентам EJB при развертывании в контейнере EJB, как и многие другие. Это позволяет создавать высококачественные многофункциональные приложения гораздо быстрее, чем можно подумать.
[1]

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

  • Создание пула:для каждого компонента EJB платформа EJB создает пул совместно используемых клиентами экземпляров компонента. В любой момент времени каждый экземпляр из пула может использоваться только одним клиентом. После завершения обслуживания клиента экземпляр возвращается в пул для повторного использования вместо уничтожения и восстановления сборщиком мусора.
  • Многопоточная ориентированность: EJB делает все компоненты ориентированными на многопоточное исполнение и высокопроизводительными. Это означает, что серверные компоненты можно писать так же, как и однопоточные настольные приложения. Сложность компонента не имеет значения. Многопоточное исполнение обеспечивается технологией EJB.
  • Транзакции: EJB поддерживает управление объявленными транзакциями, которое позволяет добавить транзакционное поведение к компонентам путем настройки, а не программирования. В результате можно сделать транзакционным любой метод компонента. При нормальном завершении метода EJB подтверждает транзакцию и сохраняет сделанные методом изменения. В противном случае выполняется откат транзакции. Транзакции EJB, управляемые контейнером, продемонстрированы в разделеРаздел 9: интеграция транзакционной бизнес-логики.
  • Безопасность: EJB поддерживает интеграцию с интерфейсом API службы проверки подлинности и авторизации Java (JAAS), поэтому теперь легче выстроить безопасность и защитить приложения, используя несложные настройки, вместо того, чтобы загромождать программу кодами безопасности. [2]В разделе 11:Обеспечение безопасности приложенийбыла продемонстрирована аннотация <a href="http://download.oracle.com/javaee/6/api/javax/annotation/security/RolesAllowed.html" target="_blank"@RolesAllowed EJB.

Сохранение состояния Java

В контексте Java Enterprise сохранение состояния — это автоматическое сохранение данных из объектов Java в реляционной базе данных. Интерфейс API сохранения состояния Java (Java Persistence API, JPA) — технология объектно-реляционного сопоставления (ORM), позволяющая приложению прозрачным для разработчика образом управлять данными в объектах Java и реляционной базе данных. Это означает, что можно применить JPA к проекту, добавив и настроив набор классов (сущностей), соответствующих модели данных. После этого приложение сможет получать доступ к этим сущностям как при прямом доступе к базе данных.

Преимущества использования JPA:

  • Для выполнения статических и динамических запросов в JPA используется собственный язык запросов, схожий с SQL. При использовании языка запросов Java Persistence Query Language (JPQL) приложения можно переносить между базами данных различных поставщиков.
  • Можно избежать написания низкоуровневого кода JDBC/SQL.
  • JPA предоставляет прозрачные службы для кэширования данных и оптимизации производительности.

Общие сведения о сеансных компонентах

Сеансные компоненты уровня предприятия вызываются клиентом для выполнения конкретных бизнес-операций. Слово сеансные означает, что экземпляры компонентов доступны в течение "периода обработки". Спецификация EJB 3.1 описывает следующие характеристики типичного сеансного объекта:

  • Выполнение для одного клиента
  • Способность работать с транзакциями
  • Обновление данных в основной базе данных
  • Отсутствие прямого представления общих данных из базы данных несмотря на возможность использования и обновления таких данных
  • Непродолжительное время существования
  • Удаление при сбое контейнера EJB Для продолжения вычислений клиент должен повторно установить сеансный объект.

EJB предоставляет три вида сеансных компонентов: с поддержкой состояния, без поддержки состояния и одноэкземплярные. Следующие определения взяты из учебного курса Java EE 6.

  • С поддержкой состояния: состояние компонента сохраняется между вызовами методов. "Состояние" – это значения переменных экземпляра. Поскольку клиент взаимодействует с компонентом, это состояние часто называют диалоговым.
  • Без поддержки состояния: такие компоненты используется для операций, происходящих в течение одного вызова метода. При завершении выполнения метода состояние, зависящее от клиента, не сохраняется. Компонент без сохранения состояния не поддерживает диалоговое состояние с клиентом.
  • Одноэкземплярный: одноэкземплярный сеансный компонент создается в приложении в единственном числе и существует в течение всего жизненного цикла приложения. Одноэкземплярные сеансные компоненты созданы для ситуаций, в которых один экземпляр компонента уровня предприятия совместно и одновременно используется клиентами.

Дополнительные сведения о сеансных компонентах EJB приведены в документе Учебный курс Java EE 6: общие сведения о сеансных компонентах.

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


Спецификации и реализации

Технологии EJB и JPA определены в следующих спецификациях:

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

Подробные сведения о технических спецификациях Java и их формальной стандартизации приведены в описании Java Community Process.

На странице загрузки окончательной редакции спецификаций EJB и JPA находятся ссылки на следующие примеры реализации:

Примеры реализации спецификации JPA называются поставщиками сохранения состояния, а поставщиком сохранения состояния, который был выбран в качестве эталонной реализации для спецификации JPA, версия 2.0, является EclipseLink.

Ссылка на пример эталонной реализации EJB также приведет на страницу, где упомянуты не только реализации EJB, но и все примеры реализации, предоставленные проектом GlassFish. Причиной является то, что проект GlassFish предоставляет эталонную реализацию спецификации JSR 316 для платформы Java EE 6. Сервер приложений GlassFish, версия 3 (или версия с открытым исходным кодом), который используется в данном учебном курсе для создания проекта по интернет-коммерции, содержит эталонные реализации всех технологий, разработанных в проекте GlassFish. В связи с этим такой сервер приложений называют контейнером Java EE 6.

Контейнер Java EE содержит три необходимых компонента: веб-контейнер (например, сервлет), контейнер EJB и поставщик сохранения состояния. Сценарий развертывания приложения электронной коммерции показан на диаграмме. Классы сущностей, создаваемые в этой главе, управляются поставщиком сохранения состояния. Создаваемые в этой главе сеансные компоненты управляются контейнером EJB. Представления отображаются страницами JSP, которые управляются веб-контейнером.

Контейнер Java EE GlassFish в3

Добавление классов сущностей

Вначале используйте мастер создания классов сущностей из базы данных в среде IDE для создания классов сущностей на основе схемы affablebean. При выполнении этого действия мастеру требуется поставщик сохранения состояния.

  1. Откройтеснимок проекта в среде IDE. В IDE нажмите Ctrl-Shift-O (âŚ�-Shift-O в Mac) и перейдите к местоположению на компьютере, где был распакован загруженный файл.
  2. Нажмите сочетание клавиш CTRL+N (⌘-N на компьютере Mac) для открытия мастера создания файлов.
  3. Выберите категорию "Сохранение состояния" и затем "Классы сущностей из базы данных". Нажмите кнопку "Далее".
  4. На втором экране мастера "Таблицы базы данных" выберите в списке источников данных jdbc/affablebean. Выпадающий список заполняется зарегистрированными на сервере приложений источниками данных.

    При выборе источника данных jdbc/affablebean среда IDE сканирует базу данных и перечисляет таблицы в панели "Доступные таблицы".
    Классы сущностей из мастера баз данных
  5. Нажмите кнопку "Добавить", а затем - кнопку "Далее".
  6. Step 3 of the Entity Classes from Database wizard differs slightly between IDE NetBeans 6.8 and 6.9. В зависимости от используемой версии IDE выполните следующие шаги.

    IDE NetBeans 6.8

    Классы сущностей из мастера баз данных, Step 3: Классы сущностей
    1. Введите название сущности в поле "Пакет". После завершения работы мастера будет создан новый пакет для классов сущностей.
    2. Нажмите кнопку "Создать блок сохранения состояния". Будет открыто диалоговое окно "Создание блока сохранения состояния".
      Диалоговое окно "Создание блока сохранения состояния".
      Блок сохранения состояния ссылается на набор классов сущностей приложения. Описанное выше диалоговое окно создает файл persistence.xml, который используется поставщиком сохранения состояния для определения параметров блока сохранения состояния. Обратите внимание, что для проекта по умолчанию выбран сервер EclipseLink (JPA 2.0). Оставьте для стратегии генерирования таблиц значение Нет. Это предотвращает изменения базы данных поставщиком сохранения состояния. Например, если требуется, чтобы поставщик сохранения состояния удалил базу данных, а затем снова создал ее на основе классов сущностей, можно выбрать стратегию Удалить и создать. Теперь каждый раз при развертывании проекта будет выполняться это действие.
    3. Нажмите кнопку "Создать".
    4. Отобразится третий экран "Классы сущностей". Обратите внимание, что имена классов сущностей зависят от таблиц базы данных. Например, сущность CustomerOrder связана с таблицей базы данных customer_order. Также обратите внимание, что по умолчанию выбран параметр "Создание аннотаций именованных запросов для сохраняемых полей". В этом учебном курсе будут использованы различные именованные запросы.
    5. Продолжение смотрите ниже в шаге 7.

    IDE NetBeans 6.9

    Классы сущностей из мастера баз данных, Step 3: Классы сущностей
    1. Введите название сущности в поле "Пакет". После завершения работы мастера будет создан новый пакет для классов сущностей.
    2. Обратите внимание:
      • имена классов сущностей зависят от таблиц базы данных. Например, сущность CustomerOrder связана с таблицей базы данных customer_order.
      • Параметр "Создать аннотации именованных запросов для сохраняемых полей" выбирается по умолчанию. В этом учебном курсе будут использованы различные именованные запросы.
      • Флажок "Создать блок сохранения состояния" установлен по умолчанию. Блок сохранения состояния — это набор классов сущностей приложения. Сохранение состояния определяется файлом настройки persistence.xml, который используется поставщиком сохранения состояния. Включение этого параметра означает, что мастер создает также файл persistence.xml и заполняет его параметрами по умолчанию.
  7. Нажмите кнопку "Завершить". Классы сущностей JPA будут созданы на основе таблиц базы данных affablebean. Классы сущностей можно просмотреть в окне "Проекты", развернув только что созданный пакет entity. Обратите внимание, что новый блок сохранения состояния появляется в узле "Файлы настройки".
    Окно 'Проекты' - классы сущностей отображаются в проекте

    Обратите внимание, что был создан дополнительный класс сущностей OrderedProductPK. Таблица ordered_product в модели данных использует составной первичный ключ, состоящий из первичных ключей таблиц customer_order и product. Ознакомьтесь с разделом Проектирование модели данных — создание связей "многие ко многим". Поэтому поставщик сохранения состояния создает отдельный класс сущностей для составного ключа и внедряет его в сущность OrderedProduct. Для просмотра класса откройте его в редакторе OrderedProduct. Чтобы показать, что внедряемый класс является составным первичным ключом, в JPA используется аннотация @EmbeddedId.
    public class OrderedProduct implements Serializable {
        private static final long serialVersionUID = 1L;
        @EmbeddedId
        protected OrderedProductPK orderedProductPK;

    Нажмите сочетание клавиш CTRL+ПРОБЕЛ на аннотации @EmbeddedId для вызова документации по интерфейсу API.

    Документация API вызвана в @EmbeddedId
  8. Откройте в редакторе блок сохранения состояния (persistence.xml). Для блоков сохранения состояния в среде IDE, кроме представления XML, доступно представление "Проектирование". Представление "Проектирование" позволяет удобно вносить изменения в параметры проекта, касающиеся управления поставщиком сохранения состояния.
    Представление проектирования AffableBeanPU единицы сохранения
  9. Чтобы открыть представление XML, выберите вкладку "XML" в верхней части блока сохранения состояния AffableBeanPU. Добавьте в файл следующее свойство.
    <persistence-unit name="AffableBeanPU" transaction-type="JTA">
      <jta-data-source>jdbc/affablebean</jta-data-source>
      <properties>
        <property name="eclipselink.logging.level" value="FINEST"/>
      </properties>
    </persistence-unit>
    Параметр протоколирования устанавливается в значение FINEST для просмотра всего вывода поставщика сохранения состояния при запуске приложения. Это позволяет увидеть запросы SQL к базе данных, используемые поставщиком сохранения состояния, и облегчает отладку.

    См. официальную документацию по EclipseLink, чтобы получить представление о журналировании и список всех значений журнала, в разделе "Как настроить журналирование"


Добавление сеансных компонентов

В этом разделе для создания фасада сеанса каждого созданного класса сущностей будет использован мастер среды IDE "Сеансные компоненты для классов сущностей". В каждом сеансном компоненте будут содержаться основные методы доступа к соответствующему классу сущностей.

Фасад сеанса — это шаблон проектирования, рекомендуемый программе Enterprise BluePrints. Как указано в документе Core J2EE Pattern Catalog, этот компонент пытается решить общие проблемы, возникающие в многопоточном приложении, например:

  • Жесткие связи, приводящие к прямой зависимости между клиентскими и бизнес-объектами.
  • Излишние вызовы методов между клиентом и сервером, приводящие к проблемам производительности сети.
  • Недостаточная общность стратегий доступа клиентов, что вызывает недопустимое использование бизнес-объектов.

Фасад сеанса маскирует взаимодействие основных бизнес-объектов и создает уровень служб, предоставляющий только необходимые функциональные возможности. Это позволяет скрыть от клиента сложную схему взаимодействия участников. Таким образом, сеансный компонент (т.е. фасад сеанса) управляет взаимодействием бизнес-объектов. Сеансный компонент также управляет жизненным циклом участников, создавая, находя, редактируя и удаляя их в соответствии с рабочим процессом.

  1. Нажмите сочетание клавиш CTRL+N (⌘-N на компьютере Mac) для открытия мастера создания файлов.
  2. В категории "Сохранение состояния" выберите "Сеансные компоненты для классов сущностей".
    Мастер файлов: Категория 'Сохранение состояния', компоненты Bean для типа файлов классов сущностей
  3. Нажмите кнопку "Далее".
  4. Второй экран "Классы сущностей". Обратите внимание, что все классы сущностей проекта перечислены слева в разделе "Доступные классы сущностей". Нажмите кнопку "Добавить все". Все классы сущностей перемещаются вправо в раздел "Выбранные классы сущностей".
  5. Нажмите кнопку "Далее".
  6. Третий экран "Созданные сеансные компоненты". Введите session в качестве имени пакета.
    Компоненты Bean сеанса для мастера классов сущностей - Шаг 3: Созданные компоненты Bean сеанса

    Примечание. Мастер может использоваться для создания локальных и удаленных интерфейсов к сеансным компонентам. Программирование сеансных компонентов с интерфейсами предпочтительнее (например, скрытие взаимодействия бизнес-объектов за интерфейсом позволяет отделить клиента от бизнес-логики, а при необходимости можно реализовать несколько вариантов интерфейса приложения). В то же время рассмотрение этого процесса выходит за рамки данного учебного курса. Обратите внимание, что версии EJB до 3.1 требуют реализации интерфейса для каждого сеансного компонента.

  7. Нажмите кнопку "Завершить". В среде IDE создаются сеансные компоненты для каждого класса сущностей проекта. В окне "Проекты" разверните новый пакет session для просмотра сеансных компонентов.

    Net Beans, версия 6.8 Net Beans, версия 6.9
    Окно 'Проекты' - компоненты Bean отображаются в проекте Окно 'Проекты' - компоненты Bean отображаются в проекте

    Примечание. Как показано выше, IDE NetBeans 6.9 обеспечивает незначительные усовершенствования аналогично созданию мастером компонентов сеансов для классов сущностей фасадных классов. А именно, код-заготовка, общий для всех классов, складывается в абстрактный класс, названный AbstractFacade. Работая в версии 6.9, откройте любой из созданных фасадных классов (кроме класса AbstractFacade). Видно, что этот класс расширяет AbstractFacade.

  8. Откройте сессионный фасад в редакторе, например в ProductFacade. Все редактируемые сессионные фасады создают EntityManager, используя аннотацию @PersistenceContext.
    @PersistenceContext(unitName = "AffableBeanPU")
    private EntityManager em;
    Аннотация @PersistenceContext используется для добавления в класс интерфейса EntityManager, управляемого контейнером. Другими словами, контейнер EJB проекта GlassFish используется для открытия и закрытия интерфейсов EntityManager, когда это необходимо. Элемент unitName указывает блок сохранения состояния AffableBeanPU, который был определен в файле persistence.xml приложения.

    EntityManager (диспетчер сущностей) — внутренний компонент интерфейса API сохранения состояния Java, отвечающий за сохранение состояния в базе данных. В книге EJB 3 в действии EntityManager описан следующим образом:
    Интерфейс JPA EntityManager управляет сущностями в терминах реального обеспечения служб сохранения состояния. Когда сущности сообщают поставщику JPA о своем сопоставлении с базой данных, они не сохраняют свое состояние самостоятельно. Интерфейс EntityManager считывает метаданные ORM для сущности и производит операции сохранения состояния.

Теперь приложение содержит модель сохранения состояния базы данных affablebean в форме классов сущностей JPA. Также оно содержит фасад сеанса, состоящий из компонентов уровня приложения, используемых для доступа к классам сущностей. В следующем разделе показан способ доступа к базе данных при помощи сеансных компонентов и классов сущностей.


Доступ к данным при помощи EJB

В предыдущей главе учебного курса показан способ доступа к базе данных путем настройки источника данных в GlassFish, добавления ссылки на ресурс к описателю развертывания приложения и использования тега JSTL <sql> на страницах JSP приложения. Это важный способ, поскольку он позволяет быстро настроить прототипы, включающие в себя данные из базы данных. Тем не менее, такой способ не подходит для средних и крупных приложений или приложений, управляемых командой разработчиков, так как сложен в расширении и поддержке. Более того, при разработке многоуровневого приложения или соблюдении шаблона MVC не следует хранить код доступа к данным в внешнем интерфейсе. Использование компонентов уровня предприятия с моделью сохранения состояния позволяет более полно следовать шаблону MVC благодаря разделению компонентов представления и модели.

Следующая инструкция описывает использование сеансных компонентов и компонентов сущностей в проекте AffableBean. В примере будет удален код доступа к данным JSTL, написанный ранее для страницы-указателя и страницы категории. Вместо них будут использованы методы доступа к данным сеансных компонентов, а данные будут храниться в контекстных переменных, которые доступны из внешнего интерфейса. Для начала отредактируем страницу-указатель, а затем - более сложную страницу категории.

страница-указатель

На странице-указателе требуются данные о четырех категориях продуктов. При текущих настройках теги JSTL <sql> запрашивают в базе данных сведения при каждом запросе к странице-указателю. Поскольку эта информация редко изменяется, с точки зрения производительности разумнее выполнить запрос только раз после того, как приложение будет запущено, и сохранить данные в атрибуте на уровне приложения. Этого можно добиться, добавив данный код в принадлежащий классу ControllerServlet метод инициализации.

  1. В окне "Проекты" дважды щелкните узел "Исходные пакеты" > controller > ControllerServlet, чтобы открыть его в редакторе.
  2. Объявите экземпляр CategoryFacade и примените к нему аннотацию @EJB.
    public class ControllerServlet extends HttpServlet {
    
        @EJB
        private CategoryFacade categoryFacade;
    
        ...
    }
    После добавления аннотации @EJB контейнер EJB создает экземпляр переменной categoryFacade с EJB CategoryFacade.
  3. С помощью подсказок среды IDE добавьте операторы импорта для следующих классов:
    • javax.ejb.EJB
    • session.CategoryFacade

    При нажатии Ctrl-Shift-I (⌘-Shift-I в Mac) требуемые импорты автоматически добавляются к используемому классу.

  4. Добавьте в класс следующий метод init. Веб-контейнер инициализирует сервлет, вызывая свой метод init. Это происходит только один раз после загрузки сервлета и до начала обработки запросов.
    public class ControllerServlet extends HttpServlet {
    
        @EJB
        private CategoryFacade categoryFacade;
    
        public void init() throws ServletException {
    
            // store category list in servlet context
            getServletContext().setAttribute("categories", categoryFacade.findAll());
        }
    
        ...
    }
    Здесь метод фасадного класса findAll применяется для запроса из базы данных всех записей категории Category. Затем полученный список объектов Category устанавливается в атрибут, обозначаемый строкой categories. Размещение ссылки в ServletContext означает, что ссылка действует в контексте всего приложения.

    Чтобы быстро определить подпись метода findAll подведите мышь к методу, удерживая клавишу Ctrl (⌘ в Mac). (The image below displays the popup that appears using IDE NetBeans 6.8.)

    Появится всплывающее окно, отображающее сигнатуру метода.
    Щелкните гиперссылку для перехода к методу.
  5. С помощью подсказки среды IDE добавьте аннотацию @Overrides Метод init определяется надклассом HttpServlet и сервлетом GenericServlet.
    Подсказка отображается в редакторе
    Добавление аннотации не обязательно, но дает следующие преимущества:
    • Позволяет компилятору проверить, действительно ли переопределяется метод, который предполагается переопределить.
    • Улучшает удобство восприятия, поскольку становится ясно, какие методы в исходном коде переопределяются.

    Дополнительные сведения об аннотациях приведены в курсе Учебные курсы по Java: аннотации.

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

    Дважды щелкните узел "Веб-страницы" > index.jsp в окне "Проекты", чтобы открыть файл в редакторе.
  7. Закомментируйте (или удалите) оператор <sql:query> в начале файла. Для закомментирования кода в редакторе выделите код, затем нажмите Ctrl-/ (⌘-/ в Mac).
    Фрагмент с добавленным комментарием отображается в редакторе
  8. Отредактируйте открывающий тег <c:forEach> так, чтобы его атрибут items указывал на новый атрибут контекста приложения categories.
    <c:forEach var="category" items="${categories}">
  9. Откройте дескриптор развертывания веб-проекта. Нажмите сочетание клавиш ALT+SHIFT+O (CTRL+SHIFT+O в Mac OS) и в диалоговом окне "Переход к файлу" введите web, затем нажмите кнопку "ОК".
    Диалоговое окно 'Перейти к файлу'
  10. Закомментируйте (или удалите) запись <resource-ref>. Эта запись требовалась для определения тегами <sql> источника данных, зарегистрированного на сервере. Теперь для доступа к базе данных используется JPA, и источник данных jdbc/affablebean уже был указан в блоке сохранения состояния. Подробные сведения представлены выше в разделе Представление проектирования поставщика сохранения состояния проекта.

    Выделите всю запись <resource-ref>, затем нажмите Ctrl-/ (⌘-/ в Mac).
    <!-- <resource-ref>
             <description>Connects to database for AffableBean application</description>
             <res-ref-name>jdbc/affablebean</res-ref-name>
             <res-type>javax.sql.ConnectionPoolDataSource</res-type>
             <res-auth>Container</res-auth>
             <res-sharing-scope>Shareable</res-sharing-scope>
         </resource-ref> -->
  11. Выполните проект. Нажмите кнопку 'Запустить проект' ( Кнопка 'Выполнить проект' ). В браузере откроется страница-указатель проекта, и отобразятся все четыре категории и изображения.
    Убедитесь в том, что к базе данных добавлены новые таблицы.

страница категории

Для верного отображения страницы категории требуются три элемента данных:

  1. данные о категориях: для кнопок категорий в левом столбце;
  2. выбранная категория: выбранная категория выделяется в левом столбце и ее имя отображается над таблицей продуктов;
  3. данные о продуктах в выбранной категории: для отображения продуктов в таблице.

Рассмотрим отдельно каждый элемент данных.

данные о категориях

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

  1. Откройте category.jsp в редакторе и закомментируйте (Ctrl-/; ⌘-/ в Mac) операторы JSTL <sql>, указанные в верхней части файла.
    <sql> операторы с добавленными комментариями в редакторе
  2. Отредактируйте открывающий тег <c:forEach> так, чтобы его атрибут items указывал на атрибут контекста приложения categories. Эта же операция была проведена в файле index.jsp.
    <c:forEach var="category" items="${categories}">
  3. Выполните проект для проверки текущего состояния страницы категории. Нажмите кнопку 'Запустить проект' ( Кнопка 'Выполнить проект' ). После отображения страницы-указателя в браузере щелкните одну из категорий. Кнопки категорий в левом столбце отображаются и работают ожидаемым образом.
    Убедитесь в том, что к базе данных добавлены новые таблицы.

выбранная категория

Чтобы извлечь выбранную категорию, можно использовать переменную categoryFacade, созданную ранее для поиска Category, чей идентификатор совпадает со строкой запроса.

  1. Откройте в редакторе ControllerServlet. Если он уже открыт, нажмите сочетание клавиш CTRL+TAB и выберите его во всплывающем списке.
  2. Начните реализовывать функциональность по принятию выбранной категории Найдите комментарий TODO: Implement category request (Сделать: реализовать запрос категории), удалите его и добавьте следующий код (выделен полужирным шрифтом).
    // if category page is requested
    if (userPath.equals("/category")) {
    
        // get categoryId from request
        String categoryId = request.getQueryString();
    
        if (categoryId != null) {
    
        }
    
    // if cart page is requested
    } else if (userPath.equals("/viewCart")) {
    В этом запросе вызовом функции getQueryString() извлекается идентификатор запрашиваемой категории.

    Примечание. Логика определения выбранной категории кнопками левого столбца уже реализована в category.jsp с использованием выражения EL, что сравнимо с вызовом getQueryString() в сервлете. Выражение EL: pageContext.request.queryString.

  3. Добавьте в оператор if следующую строку кода.
    // get categoryId from request
    String categoryId = request.getQueryString();
    
    if (categoryId != null) {
    
        // get selected category
        selectedCategory = categoryFacade.find(Short.parseShort(categoryId));
    }
    С помощью принадлежащего классу CategoryFacadeпоискового метода возвращается объект Category, который связан с идентификатором запрашиваемой категории. Обратите внимание, что необходимо привести categoryId к типу Short, поскольку такой тип используется в поле id класса сущностей Category.
  4. Щелкните метку ( Метка подсказки ) на левой границе для использования подсказки в редакторе для объявления selectedCategory как локальной переменной в методе doGet.
    Редактор
    Поскольку selectedCategory имеет тип Category, который не был ранее импортирован в класс, среда IDE автоматически добавляет выражение импорта для entity.Category в начало файла.
  5. Чтобы поместить полученный объект Category в контекст запроса, добавьте следующую строку.
    // get categoryId from request
    String categoryId = request.getQueryString();
    
    if (categoryId != null) {
    
        // get selected category
        selectedCategory = categoryFacade.find(Short.parseShort(categoryId));
    
        // place selected category in request scope
        request.setAttribute("selectedCategory", selectedCategory);
    }
  6. Переключитесь в редакторе к файлу category.jsp. Для этого нажмите сочетание клавиш CTRL+TAB и выберите его во всплывающем списке.
  7. Найдите текст <p id="categoryTitle"> и внесите следующие изменения.
    <p id="categoryTitle">
        <span style="background-color: #f5eabe; padding: 7px;">${selectedCategory.name}</span>
    </p>
    Теперь используется атрибут selectedCategory, помещенный в контекст запроса в ControllerServlet. С помощью ".name" в выражении EL вызывается метод getName в данном объекте Category.
  8. Переключитесь обратно на окно браузера и обновите страницу категорий. Теперь на странице отображается имя выбранной категории.
    Убедитесь в том, что к базе данных добавлены новые таблицы.

данные о продуктах в выбранной категории

Для того чтобы получить все продукты из выбранной категории, используется принадлежащий сущности Category метод getProductCollection(). Запустите вызов этого метода для selectedCategory, чтобы получить коллекцию всех Product, связанных с selectedCategory. Далее сохраните коллекцию продуктов в контексте запроса как атрибут и, наконец, сошлитесь на контекстный атрибут из представления страницы category.jsp.

  1. Добавьте следующий оператор в код ControllerServlet. Это выражение управляет запросом категории.
    // if category page is requested
    if (userPath.equals("/category")) {
    
        // get categoryId from request
        String categoryId = request.getQueryString();
    
        if (categoryId != null) {
    
            // get selected category
            selectedCategory = categoryFacade.find(Short.parseShort(categoryId));
    
            // place selected category in request scope
            request.setAttribute("selectedCategory", selectedCategory);
    
            // get all products for selected category
            categoryProducts = selectedCategory.getProductCollection();
        }
    Здесь вызов getProductCollection позволяет получить коллекцию всех продуктов Product, связанных с выбранной категорией selectedCategory.
  2. Используйте подсказку редактора для определения categoryProducts в качестве локальной переменной для метода doGet.
    Редактор
  3. Поместите коллекцию продуктов Product в контекст запроса, чтобы ее можно было извлечь из внешнего интерфейса приложения.
    // if category page is requested
    if (userPath.equals("/category")) {
    
        // get categoryId from request
        String categoryId = request.getQueryString();
    
        if (categoryId != null) {
    
            // get selected category
            selectedCategory = categoryFacade.find(Short.parseShort(categoryId));
    
            // place selected category in request scope
            request.setAttribute("selectedCategory", selectedCategory);
    
            // get all products for selected category
            categoryProducts = selectedCategory.getProductCollection();
    
            // place category products in request scope
            request.setAttribute("categoryProducts", categoryProducts);
        }
  4. Откройте в редакторе category.jsp и внесите в таблицу запросов следующее изменение.
    <table id="productTable">
    
        <c:forEach var="product" items="${categoryProducts}" varStatus="iter">
    Тег <c:forEach> теперь ссылается на набор categoryProducts. Цикл c:forEach теперь выполняется для каждого объекта Product, содержащегося в коллекции, и извлекает соответствующие данные.
  5. Для запуска проекта нажмите клавишу F6 (или сочетание клавиш fn+F6 в Mac OS) В браузере перейдите к странице категории и обратите внимание, что для каждой категории отображаются все продукты.
    Убедитесь в том, что к базе данных добавлены новые таблицы.

Этот учебный курс — краткое введение в технологии JPA и EJB. Также здесь описана роль спецификаций Java и использование примеров их реализации в сервере приложений GlassFish. Показано, как создать набор классов сущностей JPA, предоставляющих реализацию базы данных проектов на уровне Java. Затем в соответствии с шаблоном фасад сеанса показано создание набора сеансных компонентов EJB, которые расположены выше уровнем, чем классы сущностей, и предоставляют удобный доступ к ним. Наконец, проект AffableBean изменен для того, чтобы использовать новые сеансные компоненты и сущности для доступа к базе данных. Это требовалось в странице-указателе и странице категорий.

You can download snapshot 4 of the AffableBean project, which corresponds to state the project after completing this unit using IDE NetBeans 6.9.

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



Дополнительные сведения

Материалы по NetBeans

Ресурсы по EJB

Ресурсы по JPA

Ресурсы по GlassFish

Технические статьи

Книги


Ссылки

  1. ^ Адаптация EJB 3 в действии Глаза 1, раздел 1.1.2: EJB как платформа.
  2. ^EJB предоставляет множество других служб. Более подробный список приведен в книге EJB 3 в действии, глава 1, раздел 1.3.3: получение функциональных возможностей с помощью служб EJB.
get support for the NetBeans

Support


By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2018, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo