Duke's Forest — это сложное приложение, состоящее из трёх основных проектов и трёх подпроектов. На рисунке 62-1 показана архитектура трёх основных проектов, которые вы будете развёртывать: Duke’s Store, Duke’s Shipment и Duke’s Payment. В нём также показано, как Duke's Store использует проекты «Events» и «Entities».
Рис. 62-1. Приложение Duke’s Forest

В Duke’s Forest используются следующие функции платформы Java EE:
-
Сущности API персистентности Java
-
Веб-сервисы
-
Enterprise-бины
-
Контексты и инъецирование зависимостей (CDI)
-
CDI-аннотации для компонентов JavaServer Faces
-
Managed-бин CDI, используемый как корзина для покупок, с областью видимости диалога
-
Квалификаторы
-
События и обработчики событий
-
Сервлеты
-
JavaServer Faces, использующая Facelets для веб-интерфейса
-
Безопасность
-
Ограничения безопасности Java EE для бизнес-методов административного интерфейса (Enterprise-бины)
-
Ограничения безопасности для клиентов и администраторов (веб-компоненты)
-
Единый вход (SSO) для распространения аутентифицированного идентификатора пользователя из Duke's Store в Duke's Shipment
Приложение Duke's Forest имеет два основных пользовательских интерфейса, оба упакованы в WAR-файл Duke's Store:
-
Основной интерфейс, для клиентов и гостей
-
Административный интерфейс, используемый для выполнения служебных операций, таких как добавление новых элементов в каталог
Приложение Duke's Shipment также имеет пользовательский интерфейс, доступный для администраторов.
На рисунке 62-2 показано, как взаимодействуют веб-приложения и веб-сервис.
Рис. 62-2. Взаимодействие между компонентами Duke's Forest

Как показано на рис. 62-2, клиент взаимодействует с основным интерфейсом Duke's Store, а администратор взаимодействует с интерфейсом администрирования. Оба интерфейса получают доступ к фасаду, состоящему из Managed-бинов и сессионных бинов без сохранения состояния, которые, в свою очередь, взаимодействуют с объектами, представляющими таблицы базы данных. Фасад также взаимодействует с API веб-сервисов, которые получают доступ к веб-сервису Duke's Payment. После подтверждения оплаты заказа Duke's Store отправляет заказ в очередь JMS. Администратор также взаимодействует с интерфейсом Duke's Shipment, к которому можно получить доступ либо непосредственно через Duke's Shipment, либо из интерфейса администрирования Duke's Store с помощью веб-сервиса. Когда администратор утверждает отправку заказа, Duke's Shipment получает заказ из очереди JMS.
Фундаментальными строительными блоками приложения являются проекты «Events» и «Entities», которые объединяются в Duke's Store и Duke's Shipment вместе с проектом Duke's Resources.
Проект Events
События являются одними из ключевых компонентов Duke 's Forest. Проект events
, включённый во все три основных проекта, является наиболее простым проектом приложения. У него есть только один класс, OrderEvent
, но этот класс отвечает за большинство сообщений между объектами в приложении.
Приложение может отправлять сообщения на основе событий в различные компоненты и реагировать на них в зависимости от квалификации события. Приложение поддерживает следующие квалификаторы:
-
@LoggedIn
: для аутентифицированных пользователей
-
@New
: когда компонент корзины покупок создаёт новый заказ
-
@Paid
: когда заказ оплачен и готов к отправке
Следующий фрагмент кода из класса PaymentHandler
в магазине Duke's Store показывает, как обрабатывается событие @Paid
:
@Inject @Paid Event<OrderEvent> eventManager;
...
public void onNewOrder(@Observes @New OrderEvent event) {
if (processPayment(event)) {
orderBean.setOrderStatus(event.getOrderID(),
String.valueOf(OrderBean.Status.PENDING_PAYMENT.getStatus()));
logger.info("Payment Approved");
eventManager.fire(event);
} else {
orderBean.setOrderStatus(event.getOrderID(),
String.valueOf(OrderBean.Status.CANCELLED_PAYMENT.getStatus()));
logger.info("Payment Denied");
}
}
Чтобы облегчить пользователям добавление событий в проект или добавление в классы событий большего количества полей для нового клиента, этот компонент является отдельным проектом в приложении.
Проект entities
Проект entity
— это проект Java Persistence API (JPA), используемый как Duke's Store, так и Duke's Shipment. Он генерируется из схемы базы данных, показанной на рис. 62-3, и также используется в качестве базы для сущностей, потребляемых и создаваемых веб-сервисами через JAXB. У каждого объекта есть правила валидации на основе бизнес-требований, которые определяются Bean Validation.
Рис. 62-3. Таблицы базы данных Duke's Forest и их взаимосвязи

Схема базы данных содержит восемь таблиц:
-
PERSON
имеет отношение "один ко многим" с PERSON_GROUPS
и CUSTOMER_ORDER
-
GROUPS
имеет отношение "один ко многим" с PERSON_GROUPS
-
PERSON_GROUPS
имеет отношение "многие к одному" с PERSON
и GROUPS
(промежуточная таблица между этими двумя таблицами)
-
PRODUCT
имеет отношение "многие к одному" с CATEGORY
и отношение "один ко многим" с ORDER_DETAIL
-
CATEGORY
имеет отношение "один ко многим" с PRODUCT
-
CUSTOMER_ORDER
имеет отношение "один ко многим" с ORDER_DETAIL
и отношение "многие к одному" с PERSON
и ORDER_STATUS
-
ORDER_DETAIL
имеет отношение "многие к одному" с PRODUCT
и CUSTOMER_ORDER
(промежуточная таблица между этими двумя таблицами)
-
ORDER_STATUS
имеет отношение "один ко многим" с CUSTOMER_ORDER
Классы сущностей, которые соответствуют этим таблицам, следующие.
-
Person
определяет атрибуты, общие для клиентов и администраторов. Этими атрибутами являются имя человека и контактная информация, включая улицу и адреса электронной почты. Адрес электронной почты имеет аннотацию Bean Validation, чтобы гарантировать, что представленные данные правильно сформированы. Сгенерированная таблица для сущности Person
также имеет поле DTYPE
, которое представляет столбец дискриминатора. Его значение идентифицирует дочерний класс (Customer
или Administrator
), к которому принадлежит человек.
-
Customer
, дочерний для Person
с определённым полем для объектов CustomerOrder
.
-
Administrator
, дочерний для Person
с полями для привилегий администратора.
-
Groups
, представляющая группу (USERS
или ADMINS
), к которой принадлежит пользователь.
-
Product
, который определяет атрибуты для продуктов. Эти атрибуты включают имя, цену, описание, ассоциированное изображение и категорию.
-
Category
, которая определяет атрибуты для категорий товаров. Эти атрибуты включают в себя имя и набор тегов.
-
CustomerOrder
, который определяет атрибуты для заказов, размещаемых клиентами. Эти атрибуты включают сумму и дату, а также значения идентификатора для клиента и детали заказа.
-
OrderDetail
, который определяет атрибуты для деталей заказа. Эти атрибуты включают значения количества и идентификатора для продукта и клиента.
-
OrderStatus
, который определяет атрибут статуса для каждого заказа.
Проект dukes-payment
Проект dukes-payment
— это веб-проект, содержащий простой веб-сервис оплаты. Поскольку это пример приложения, оно не получает никакой реальной кредитной информации или даже статуса клиента для подтверждения платежа. На данный момент единственное правило, наложенное платёжной системой, — это запрещать все заказы на сумму свыше 1000 долларов США. Это приложение иллюстрирует общий сценарий, когда сторонняя платёжная система используется для проверки кредитных карт или банковских платежей.
В проекте используются базовая аутентификация HTTP и JAAS (сервис аутентификации и авторизации Java) для аутентификации клиента в веб-сервисе JAX-RS. Сама реализация предоставляет простой метод processPayment
, который получает OrderEvent
для оценки и утверждения или отклонения оплаты заказа. Метод вызывается из процесса оформления покупки в Duke's Store.
Проект dukes-resources
Проект dukes-resources
содержит несколько файлов, используемых как Duke's Store, так и Duke's Shipment, связанных в JAR-файл, размещённый в classpath. Ресурсы находятся в каталоге src/main/resources
:
-
META-INF/resources/css
: две таблицы стилей, default.css
и jsfcrud.css
-
META-INF/resources/img
: изображения, используемые в проектах
-
META-INF/resources/js
: файл JavaScript util.js
-
META-INF/resources/util
: составные компоненты, используемые в проектах
-
bundles/Bundle.properties
: сообщения приложений на английском языке
-
bundles/Bundle_es.properties
: сообщения приложений на испанском языке
-
ValidationMessages.properties
: сообщения Bean Validation на английском языке
-
ValidationMessages_es.properties
: сообщения Bean Validation на испанском языке
Проект Duke’s Store
Duke’s Store, веб-приложение, является основным приложением Duke's Forest. Оно отвечает за интерфейс основного магазина для клиентов, а также за интерфейс администрирования.
Основной интерфейс Duke's Store позволяет пользователю выполнять следующие задачи:
-
Просмотр каталога продукции
-
Регистрация в качестве нового клиента
-
Добавление товаров в корзину
-
Проверка
-
Просмотр статуса заказа
Интерфейс администрирования Duke's Store позволяет администраторам выполнять следующие задачи:
-
Обслуживание продукта (создание, редактирование, обновление, удаление)
-
Обслуживание категории (создание, редактирование, обновление, удаление)
-
Обслуживание клиентов (создание, редактирование, обновление, удаление)
-
Обслуживание групп (создание, редактирование, обновление, удаление)
В проекте также используются сессионные компоненты без сохранения состояния в качестве фасадов для взаимодействия с сущностями JPA, описанными в Проекте entities, и Managed-бины CDI в качестве контроллеров для взаимодействия со страницами Facelets. Таким образом, проект следует шаблону MVC (Model-View-Controller) и применяет тот же шаблон ко всем сущностям и страницам, как в следующем примере.
-
AbstractFacade
— это абстрактный класс, который получает Type<T>
и реализует общие операции (CRUD) для этого типа, где <T>
— сущность JPA.
-
ProductBean
— это сессионный компонент без сохранения состояния, который расширяет AbstractFacade
, применяя Product
как Type<T>
и инъецирует PersistenceContext
для EntityManager
. Этот бин реализует все пользовательские методы, необходимые для взаимодействия с сущностью Product
или для вызова пользовательского запроса.
-
ProductController
— это Managed-бин CDI, который взаимодействует с необходимыми Enterprise-бинами и страницами Facelets для управления отображением данных.
ProductBean
начинается следующим образом:
@Stateless
public class ProductBean extends AbstractFacade<Product> {
private static final Logger logger =
Logger.getLogger(ProductBean.class.getCanonicalName());
@PersistenceContext(unitName="forestPU")
private EntityManager em;
@Override
protected EntityManager getEntityManager() {
return em;
}
...
Enterprise-бины, используемые в Duke’s Store
Enterprise-бины, используемые в Duke's Store, обеспечивают бизнес-логику для приложения и находятся в пакете com.forest.ejb
. Все сессионные компоненты без состояния.
AbstractFacade
— это не Enterprise-бин, а абстрактный класс, который реализует общие операции для Type<T>
, где <T>
— сущность JPA.
Большинство других бинов расширяют AbstractFacade
, инъецируют PersistenceContext
и реализуют все необходимые пользовательские методы:
-
AdministratorBean
-
CategoryBean
-
EventDispatcherBean
-
GroupsBean
-
OrderBean
-
OrderDetailBean
-
OrderJMSManager
-
OrderStatusBean
-
ProductBean
-
ShoppingCart
-
UserBean
Класс ShoppingCart
, хотя он находится в пакете ejb
, является Managed-бином CDI с областью видимости диалога, что означает, что информация запроса будет сохраняться в нескольких запросах. Кроме того, ShoppingCart
отвечает за запуск цепочки событий для заказов клиентов, которая вызывает RESTful веб-сервис в dukes-payment
и публикует заказ в очереди JMS для подтверждения доставки, если оплата прошла успешно.
Файлы Facelets, используемые в основном интерфейсе Duke's Store
Как и в других примерах, в Duke's Store для отображения пользовательского интерфейса используются Facelets. Основной интерфейс использует большое количество страниц Facelets для отображения. Страницы сгруппированы в каталоги в зависимости от того, какой модуль они обрабатывают.
-
template.xhtml
: файл шаблона, используемый как для основного, так и для административного интерфейсов. Сначала выполняется проверка браузера, чтобы убедиться, что браузер пользователя поддерживает HTML 5, что необходимо для Duke's Forest. Он разделяет экран на несколько областей и определяет страницу клиента для каждой области.
-
topbar.xhtml
: страница для области входа в систему в верхней части экрана.
-
top.xhtml
: страница для области заголовка.
-
left.xhtml
: страница для левой боковой панели.
-
index.xhtml
: страница для содержимого основного экрана.
-
login.xhtml
: страница входа указана в web.xml
. Основной интерфейс входа в систему представлен в topbar.xhtml
, но эта страница появляется в случае ошибки входа.
-
Каталог admin
: страницы, связанные с интерфейсом администрирования, описанным в Файлы Facelets, используемые в интерфейсе администрирования Duke's Store.
-
Каталог customer
: страницы, связанные с клиентами (Create.xhtml
, Edit.xhtml
, List.xhtml
, Profile.xhtml
, View.xhtml
).
-
Каталог order
: страницы, связанные с заказами (Create.xhtml
, List.xhtml
, MyOrders.xhtml
, View.xhtml
).
-
Каталог orderDetail
: всплывающая страница, позволяющая пользователям просматривать детали заказа (View_popup.xhtml
).
-
Каталог product
: страницы, связанные с продукцией (List.xhtml
, ListCategory.xhtml
, View.xhtml
).
Файлы Facelets, используемые в интерфейсе администрирования Duke's Store
Страницы Facelets для интерфейса администрирования Duke's Store находятся в каталоге web/admin
:
-
Каталог administrator
: страницы, связанные с управлением администраторами (Create.xhtml
, Edit.xhtml
, List.xhtm`l, `View.xhtml
)
-
Каталог category
: страницы, связанные с управлением категориями товаров (Create.xhtml
, Edit.xhtml
, List.xhtml
, View.xhtml
)
-
Каталог customer
: страницы, связанные с управлением клиентами (Create.xhtml
, Edit.xhtml
, List.xhtml
, Profile.xhtml
, View.xhtml
)
-
Каталог groups
: страницы, связанные с управлением группами (Create.xhtml
, Edit.xhtml
, List.xhtml
, View.xhtml
)
-
Каталог order
: страницы, связанные с управлением заказами (Create.xhtml
, Edit.xhtml
, List.xhtml
, View.xhtml
)
-
Каталог orderDetail
: всплывающая страница, позволяющая администратору просматривать детали заказа (View_popup.xhtml
)
-
Каталог product
: страницы, связанные с управлением продукцией (Confirm.xhtm`l, `Create.xhtml
, Edit.xhtml
, List.xhtml
, View.xhtml
)
Managed-бины, используемые в Duke’s Store
В Duke's Store используются следующие Managed-бины CDI, соответствующие Enterprise-бинам. Бины находятся в пакете com.forest.web
:
-
AdministratorController
-
CategoryController
-
CustomerController
-
CustomerOrderController
-
GroupsController
-
OrderDetailController
-
OrderStatusController
-
ProductController
-
UserController
Вспомогательные классы, используемые в Duke’s Store
Managed-бины CDI в главном интерфейсе Duke's Store используют следующие вспомогательные классы, которые находятся в пакете com.forest.web.util
:
-
AbstractPaginationHelper
: абстрактный класс с методами, используемыми Managed-бинами
-
ImageServlet
: класс сервлета, который извлекает содержимое изображения из базы данных и отображает его
-
JsfUtil
: класс, используемый для операций JavaServer Faces, таких как сообщения очереди в объекте FacesContext
-
MD5Util
: класс, используемый Managed-бином CustomerController
для генерации зашифрованного пароля пользователя
Квалификаторы, используемые в Duke's Store
Duke's Store определяет следующие квалификаторы в пакете com.forest.qualifiers
:
-
@LoggedIn
: квалифицирует пользователя как вошедшего в систему
-
@New
: квалифицирует заказ как новый
-
@Paid
: квалифицирует заказ как оплаченный
Обработчики событий, используемые в Duke's Store
В Duke's Store определены обработчики событий, связанные с классом OrderEvent
, упакованным в проекте events
(см. Проект events). Обработчики событий находятся в пакете com.forest.handlers
.
-
IOrderHandler
: интерфейс IOrderHandler
определяет метод onNewOrder
, реализованный двумя классами-обработчиками.
-
PaymentHandler
: компонент ShoppingCart
запускает OrderEvent
, квалифицированный как @New
. Метод onNewOrder
в PaymentHandler
наблюдает за этими событиями и, когда он их перехватывает, обрабатывает платёж с помощью веб-сервиса Duke's Payment. После успешного ответа от веб-сервиса PaymentHandler
снова запускает OrderEvent
, на этот раз квалифицированный как @Paid
.
-
DeliveryHandler
: метод onNewOrder
для DeliveryHandler
наблюдает за объектами OrderEvent
, квалифицированными как @Paid
( заказы оплачены и готовы к доставке) и изменяет статус заказа на PENDING_SHIPMENT
. Когда администратор получает доступ к Duke's Shipment, он вызывает сервис заказов, RESTful веб-сервис, и запрашивает все заказы в базе данных, которые готовы к доставке.
Дескрипторы развёртывания, используемые в Duke's Store
В Duke's Store используются следующие дескрипторы развёртывания, расположенные в каталоге web/WEB-INF
:
-
faces-config.xml
: файл конфигурации JavaServer Faces
-
glassfish-web.xml
: файл конфигурации, специфичный для сервера GlassFish
-
web.xml
: файл конфигурации веб-приложения
Проект Duke’s Shipment
Duke's Shipment — это веб-приложение со страницей входа, главной страницей Facelets и некоторыми другими объектами. Это приложение, которое доступно только администраторам, получает заказы из очереди JMS и вызывает RESTful веб-сервис, предоставляемый Duke's Store, для обновления статуса заказа. На главной странице Duke's Shipment отображается список заказов, ожидающих отправки, и список отправленных заказов. Администратор может утверждать или отклонять заказы на доставку. В случае одобрения заказ доставляется и отображается под заголовком «Отправлено». В случае отклонения заказ исчезает со страницы, а в списке заказов клиента он отображается как отменённый.
В списке «Ожидание» также есть значок шестерёнки, который выполняет Ajax-вызов в службу заказов, чтобы обновить список без обновления страницы. Код выглядит так:
<h:commandLink>
<h:graphicImage library="img" title="Check for new orders"
style="border:0px" name="refresh.png"/>
<f:ajax execute="@form" render="@form" />
</h:commandLink>
Enterprise-бины, используемые в Duke’s Shipment
UserBean
сессионный компонент без сохранения состояния, используемый в Duke's Shipment, обеспечивает бизнес-логику для приложения и находится в пакете com.forest.shipment.session
.
Как и Duke's Store, в Duke’s Shipment используется класс AbstractFacade
. Этот класс является не Enterprise-бином, а абстрактным классом, который реализует общие операции для Type<T>
, где <T>
— сущность JPA.
OrderBrowser
сессионный компонент без сохранения состояния, расположенный в пакете com.forest.shipment.ejb
, имеет один метод, который просматривает очередь JMS заказов, и другой, который использует сообщение заказа после того как администратор утверждает или отклоняет заказ на отправку.
Файлы Facelets, используемые в Duke's Shipment
В Duke's Shipment есть только одна страница, поэтому в ней больше файлов Facelets, чем в Duke's Store.
-
template.xhtml
: файл шаблона, как и файл в Duke's Store, сначала выполняет проверку браузера, чтобы убедиться, что браузер пользователя поддерживает HTML 5, что требуется для Duke's Forest. Он делит экран на области и определяет страницу клиента для каждой области.
-
topbar.xhtml
: страница для области входа в систему в верхней части экрана.
-
top.xhtml
: страница для области заголовка.
-
index.xhtml
: страница для начального содержимого основного экрана.
-
login.xhtml
: страница входа указана в web.xml
. Основной интерфейс входа в систему представлен в topbar.xhtml
, но эта страница появляется в случае ошибки входа.
-
admin/index.xhtml
: страница для содержимого основного экрана после аутентификации.
Managed-бины, используемые в Duke’s Shipment
Duke's Shipment использует следующие Managed-бины CDI в пакете com.forest.shipment
:
-
web.ShippingBean
: Managed-бин, действующий в качестве клиента для сервиса заказов
-
web.UserController
: Managed-бин, соответствующий сессионному компоненту UserBean
Класс помощника, используемый в Duke’s Shipment
Managed-бины Duke's Shipment используют только один вспомогательный класс, который находится в пакете com.forest.shipment.web.util
:
Квалификатор, используемый в Duke’s Shipment
Дескрипторы развёртывания, используемые в Duke’s Shipment
Duke's Shipment использует следующие дескрипторы развёртывания:
-
faces-config.xml
: файл конфигурации JavaServer Faces
-
glassfish-web.xml
: файл конфигурации, специфичный для сервера GlassFish
-
web.xml
: файл конфигурации веб-приложения