
- •Введение
- •1 Тема 1. Предметная область и терминология РСОС
- •1.1 Этапы развития распределенных систем
- •1.1.1 Классификация систем обработки данных
- •1.1.2 Распределенные вычислительные сети
- •1.1.3 Объектные распределенные системы
- •1.2 Становление систем с сервис-ориентированной архитектурой
- •1.2.1 Развитие web-технологий
- •1.2.2 Развитие концепции SOA
- •1.3 Современные парадигмы сервис-ориентированных архитектур
- •1.3.1 Эталонная модель SOA
- •1.3.2 Модель Захмана
- •1.3.3 Концепция среды открытой системы
- •1.3.4 Бизнес-парадигма модели SOA
- •1.4 Программная платформа Java Enterprise Edition
- •1.4.1 Контейнеры и компоненты Java EE
- •1.4.2 Служебные сервисы контейнеров
- •1.4.3 Артефакты контейнеров
- •1.4.4 Аннотации и дескрипторы развертывания
- •1.4.5 Управляемые компоненты платформы Java EE
- •1.5 Инструментальные средства реализации РСОС
- •1.5.1 Сервера приложений
- •1.5.2 Микросервисы
- •1.5.3 Apache Maven — сетевая сборка приложений
- •1.5.4 Eclipse Enterprise Edition
- •1.5.5 Тестовый пример
- •1.6 Заключение по первой главе
- •1.6.1 Итоги теоретических построений первой главы
- •1.6.2 Тематический план последующих глав
- •Вопросы для самопроверки
- •2 Тема 2. Использование компоненты JSF контейнера Web
- •2.1.1 Языки HTML, JavaScript и протокол HTTP
- •2.1.2 Серверные технологии PHP и HttpServlet
- •2.1.3 Технология AJAX и компонента JavaServer Faces
- •2.2 Шаблон проектирования MVC
- •2.2.1 Контроллер FacesServlet и жизненный цикл запроса
- •2.2.2 Контекст состояния запроса FacesContext
- •2.2.3 Модель в виде компонентов-подложек
- •2.2.4 Представление (View) средствами Facelets
- •2.2.5 JSF OmniFaces
- •2.3 Реализация тестового примера средствами JSF
- •2.3.1 Создание Facelets-шаблона изучаемой дисциплины
- •2.3.2 Прямая реализация тестового примера
- •2.4 Реализация уровня интерфейса сервисов
- •2.4.2 Компонента Users с ЖЦ @ApplicationScoped
- •2.4.3 Компонента RSOS с ЖЦ @SessionScoped
- •2.4.4 Компоненты-подложки с ЖЦ @RequestScoped
- •2.4.5 Приложение авторизации пользователя
- •2.4.6 Компонента подзаголовка проекта
- •2.4.7 Компонента меню лабораторных работ
- •2.4.8 Второй вариант меню лабораторных работ
- •Вопросы для самопроверки
- •3 Тема 3. Современные способы доступа к данным
- •3.1 Учебная инфраструктура темы
- •3.1.1 Учебная задача Letters (Письма)
- •3.1.2 Корпоратиные EJB-компоненты
- •3.1.3 Тестовый HttpServlet проекта lab4
- •3.1.4 Инфраструктура сервера TomEE и СУБД Derby
- •3.2 Технология JPA
- •3.2.1 Сущности
- •3.2.2 Объектно-реляционное отображение
- •3.2.3 Манеджер сущностей
- •3.2.4 Пример использования не-JTA-типа транзакций
- •3.3 Транзакции управляемые контейнером
- •3.3.1 Объектно-ориентированные запросы Criteria API
- •3.3.2 Реализация EJB-компонента с JTA-типом транзакций
- •3.3.3 Реализация JPA-сервлета
- •Вопросы для самопроверки
- •4 Тема 4. Обработка документов XML и JSON
- •4.1 Технология JAXB
- •4.1.1 Программное обеспечение технологии JAXB
- •4.1.2 Аннотации для связывания объектов Java
- •4.1.3 Преобразование объекта Java в документ XML
- •4.2 Технология JSON
- •4.2.1 Программное обеспечение технологии JSON
- •4.2.2 Преобразование объекта Java в документ JSON
- •4.2.3 Пример представления JSON на уровне классов
- •4.2.4 Выводы по результатам изучения главы 4
- •Вопросы для самопроверки
- •5 Тема 5. Web-службы SOAP
- •5.1.1 Протоколы и языки Web-служб
- •5.1.2 Краткое описание языка WSDL
- •5.1.3 Краткое описание протокола SOAP
- •5.1.4 Необязательный реестр Web-служб — UDDI
- •5.1.5 Программные пакеты Java EE, обслуживающие SOAP
- •5.2 Создание Web-служб SOAP
- •5.2.1 Подготовка проекта lab7
- •5.2.2 Аннотации поставщика Web-сервиса
- •5.2.3 Обработка исключений поставщика Web-сервиса
- •5.2.4 Обработка контекста Web-сервиса
- •5.3 Создание потребителя Web-службы SOAP
- •5.3.1 Аннотации для потребителей сервиса
- •5.3.2 Использование утилиты wsimport
- •5.3.3 Реализация тестового примера
- •5.3.4 Выводы по результатам изучения главы 5
- •Вопросы для самопроверки
- •6 Тема 6. Web-службы в стиле REST
- •6.1 Основные положения технологии RESTful
- •6.1.1 Ресурсы, URI, представления и адресуемость
- •6.1.2 Протокол HTTP
- •6.1.3 Языки WADL и HAL
- •6.1.4 Технология JAX-RS
- •6.2 Реализация Web-службы в стиле REST
- •6.2.1 Преобразование сущности Letter
- •6.2.2 Реализация EJB-компоненты Lets9
- •6.2.3 Получение списка записей в формате XML
- •6.2.4 Получение записи по номеру индентификатора
- •6.2.5 Добавление новой записи
- •6.3 Вызов Web-служб в стиле REST
- •6.3.1 Инструментальные средства потребителя сервиса
- •6.3.2 Полная реализация RESTfull-сервиса
- •6.3.3 Шаблон реализации потребителя сервиса
- •6.3.4 Клиент, реализующий методы GET и POST
- •6.3.6 Клиент, реализующий методы DELETE и PUT
- •Вопросы для самопроверки
- •Заключение
- •Список использованных источников
- •Алфавитный указатель

2.3.2 Прямая реализация тестового примера
Наиболее сильная сторона технологии JSP — прямое взаимодействие ресурсов представления информации с бизнес-уровнем компонент-подложек.
Для прямой реализации тестового приложения, ранее созданного на основе сервлета HttpServlet, имеются все необходимые условия:
а) создан проект labs, включающий в себя компоненту JSF; б) имеется новый Facelets-шаблон учебной дисциплины;
в) имеется компонента-подложка в виде POJO-класса TestTomee, реализующая бизнес-модель тестового примера (см. листинг 2.1 на стр. 77);
г) отсутствует только XHTML-ресурс представления решаемой задачи, который бы связывал отображаемое в браузере представление задачи с с бизнес-подложкой модели.
Реализуем недостающую часть приложения тестовой задачи на основе файла lab3.xhtml, который уже включен в структуру шаблона учебной дисциплины (см. листинг 2.14 на стр. 93-94). Сачала запустим тестовое приложение (см. рисунок 2.21) и перечислим графические компоненты, которые должен содержать файл lab3.xhtml.
Рисунок 2.21 — Интерфейс тестового приложения
В интерфейсе тестового приложения можно выделить три части, пред-
93

ставленные в таблице 2.8.
Таблица 2.8 — Основные части интерфейса тестового приложения
№ части |
Описание |
1 |
Вывод метода обращения к серверу и идентификатора сессии. |
2 |
Вывод списка отправленных приложению сообщений. |
3 |
Форма ввода текста и командная кнопка отправки тестовому |
|
приложению нового сообщения. |
Хорошо видно, что каждая из выделенных частей приложения требует ввода или вывода информации сосредоточенной в объектах компонентов-подло- жек или в объектах компоненты JSF.
Проведем последовательную реализацию тестового приложения согласно выделенным в таблице частям, предварительно изучив необходимую для этого теоретическую базу.
Для связывания страниц JSF с компонентами-подложками используется язык выражений
EL (Expression Language).
Базовый синтаксис утверждения языка выражений имеет вид #{expr}, который будет оцениваться и преобразовываться во время выполнения JSF.
Основные операторы EL:
а) арифметические: + , – , * , / (деление), % (целая часть);
б) операторы отношений: == (равно), != (не равно), < (меньше), > (больше), <= (меньше либо равно), >= (больше либо равно);
в) логические: && (и), || (или), ! (не);
г) другие: () (вызов метода), empty (логическая проверка на null), [] (как и оператор «точка» - доступ к атрибуту).
Компоненты-подложки — это CDI-объекты POJO-классов, имеющих имя класса, имена публичных методов и имена приватных данных (простых типов или объектных).
Доступ к целевым приватным данным компонентов-подложек осуществляется через имена классов, причем используется «верблюжья нотация», требующая, чтобы имя класса указвалось со строчной буквы. Например, компо- нента-подложка TestTomee проекта labs имеет приватную строковую переменную text (см. листинг 2.1, стр. 77-78):
94

Для обращения к этой переменной со страницы JSF следует использовать синтаксис: "#{testTomee.text}".
Обратите внимание, что в приведенном примере класс TestTomee должен иметь реализацию методов:
−для чтения из text: public String getText() {...};
−для записи в text: public void setText(String text) {...}.
Страницы JSF имеют доступ ко множеству неявных объектов, представленных в таблице 2.9.
Теперь у нас имеются все необходимые знания для реализации первой части тестового приложения, которая требует вывода метода доступа к серверу в HTTP-запросе и идентификатора сессии, в пределах которой осуществляется запрос.
Поскольку в таблице 2.8 присутствуют неявные объекты request и session, то воспользуемся их методами для доступа к нужной информации.
Ранее, нужная нам информация извлекалась в тестовом примере (см. пункт 1.5.5 главы 1). Там JSP-страница test.jsp (см. листинг 1.2, стр. 55) содержала выражения:
Зная назначение и структуру POJO-классов (JavaBeans) и синтаксис применения языка выражений EL, мы понимаем, что:
а) метод доступа можно получить выражением: "#{request.method}"; б) идентификатор сессии можно получить выражением: "#{session.id}".
Часть 1 тестового приложения реализуется в Facelets-компоненте нового шаблона с идентификатором subheader.
Исходя из этого условия, переопределим компоненту subheader JSF-стра- ницы lab3.xhtml, как это приведено в листинге 2.17.
95
Таблица 2.9 — Неявные объекты, доступные на страницах JSF [17]
Неявный объект |
Описание |
Возвращаемый тип |
application |
Представляет среду веб-приложения. Ис- |
Object |
|
пользуется для получения конфигурацион- |
|
|
ных параметров приложения. |
|
applicationScope |
Преобразует имена глобальных атрибутов |
Map |
|
приложения в их значения. |
|
component |
Указывает на текущий компонент. |
UIComponent |
cc |
Указывает на текущий составной компо- |
UIComponent |
|
нент. |
|
cookie |
Определяет объект типа Map, содержащий |
Map |
|
имена cookies (являющиеся ключами) и |
|
|
объекты типа Cookie. |
|
facesContext |
Указывает на объект типа FacesContext для |
FacesContext |
|
текущего запроса. |
|
flash |
Представляет объект, использующий флеш. |
Object |
header |
Преобразует имя HTTP-заголовка в значе- |
Map |
|
ние заголовка типа String. |
|
headerValues |
Преобразует имя HTTP-заголовка в набор |
Map |
|
всех значений заголовка типа String[]. |
|
initParam |
Преобразует имена параметров инициали- |
Map |
|
зации контекста к значениям типа String. |
|
param |
Преобразует имена параметров запроса к |
Map |
|
одному значению параметра типа String. |
|
paramValues |
Преобразует имена параметров запроса к |
Map |
|
набору всех значений параметра типа |
|
|
String[]. |
|
request |
Представляет объект запроса HTTP. |
Object |
requestScope |
Преобразует имена атрибутов запроса к их |
Map |
|
значениям. |
|
resource |
Представляет объект ресурса. |
Object |
session |
Представляет объект сеанса НТТР. |
Object |
sessionScope |
Преобразует имена атрибутов сеанса к их |
Map |
|
значениям. |
|
view |
Представляет текущее представление. |
UIViewRoot |
viewScope |
Преобразует имена атрибутов представле- |
Map |
|
ния к их значениям. |
|
Листинг 2.17 — Первая часть реализации lab3.xhtml проекта labs
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
96

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:c="http://xmlns.jcp.org/jsp/jstl/core" xmlns:f="http://xmlns.jcp.org/jsf/core" xml:lang="ru">
<ui:composition template="/WEB-INF/templates/lab3Templ.xhtml"> <!-- Переопределение подзаголовка subheader-->
<ui:define name="subheader">
<!-- Часть 1 реализации тестового примера --> <div style="background-color:gray;width:100%;
color:white;padding:5px">
<b>Вызван метод: #{request.method};</b> ID сессии: #{session.id} </div>
</ui:define>
</ui:composition> </html>
Результат реализации этой части приложения показан на рисунке 2.22. Обратите внимание, что компонента context не изменилась.
Рисунок 2.22 — Результат реализации первой части тестового приложения
97

Вторая часть тестового приложения, согласно таблице 2.8, должна выводить список отправленных приложению сообщений. Здесь следует напомнить, что отправленные сообщения храняться в компоненте-подложке класса TestTomee (см. листинг 2.1 на стр. 77-78) в виде списка строк msgs типа List<String>. Этот список строк необходимо прочитать на страние lab3.xhtml, а затем представить для обозрения.
JSF имеет четыре основных тега вывода, представленных в таблице 2.10 и способных с помощью EL отображать информцию связанную с компонентами-подложками, а также — тег цикла: <c:forEach>.
Таблица 2.10 — Теги вывода [17]
Тег |
Описание |
<h:outputLabel> |
Отображает элемент HTML <label>. |
<h:outputLink> |
Отображает элемент привязки HTML <a>. |
<h:outputText> |
Выводит текст. |
<h:outputFormat> |
Отрисовывает параметризованный текст. |
Рассмотрим применение тегов <c:forEach> и <h:outputLabel> на примере реализации второй части тестового приложения. Эта часть будет переопределять компоненту шаблона context, что показано на рисуке 2.23.
Рисунок 2.23 — Демонстрация использования тегов <c:forEach> и <h:outputLabel>
Результат работы реализованных двух частей тестового приложения показан на рисунке 2.24.
98

Рисунок 2.24 — Результат работы двух частей тестового приложения
Обратите внимание, что на рисунке 2.24 никаких сообщений не показано, потому что еще не реализованы средства ввода сообщений.
Основными средствами интерактивного взаимодействия JSF-страниц и компонент-подло- жек являются теги ввода информации (см. таблица 2.11) и теги команд (см. таблица 2.12).
Таблица 2.11 — Теги компонентов ввода [17]
Тег |
Описание |
<h:inputHidden> |
Представляет HTML-элемент ввода для скрытых данных (полезен для |
|
переноса значений от страницы к странице вне сессии). |
<h:inputSecret> |
Представляет HTML-элемент ввода для паролей. При повторной |
|
загрузке страницы любое ранее введенное значение не будет |
|
отображено , если только свойство redisplay не имеет значения true. |
<h:inputText> |
Представляет HTML-элемент ввода для текста. |
<h:inputTextarea> |
Представляет текстовую область в HTML. |
<h:inputFile> |
Позволяет просматривать каталог, выбирать и загружать файл. |
99
|
Таблица 2.12 — Теги команд [17] |
Тег |
Описание |
<h:commandButton> |
Представляет HTML-элемент, предназначенный для ввода данных |
|
кнопок «Отправить» или «Очистить». |
<h:commandLink> |
Представляет HTML-элемент для гиперссылки, который действует |
|
как кнопка «Отправить». Этот компонент должен быть помещен |
|
внутрь формы. |
Используя выделенные красным цветом теги, можно легко реализовать третью часть тестового приложения, что:
а) тег <h:inputTextarea> читает и записывает приватный атрибут text класса
TestTomee;
б) <h:commandButton> обращается к методу addMessage() того же класса.
Реализация третьей части приложения офрмляется тегом <h:form> и вставляется в компоненту context после второй части.
Общий результат реализации приложения в виде файла lab3.xhtml представлен на листинге 2.18.
Листинг 2.18 — Полная реализация lab3.xhtml проекта labs
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:c="http://xmlns.jcp.org/jsp/jstl/core" xmlns:f="http://xmlns.jcp.org/jsf/core" xml:lang="ru">
<ui:composition template="/WEB-INF/templates/lab3Templ.xhtml">
<!-- Переопределение подзаголовка subheader--> <ui:define name="subheader">
<!-- Часть 1 реализации тестового примера --> <div style="background-color:gray;width:100%;
color:white;padding:5px">
<b>Вызван метод: #{request.method};</b> ID сессии: #{session.id}
</div>
</ui:define>
<!-- Переопределение контекстной страницы context --> <ui:define name="context">
<!-- Часть 2 реализации тестового примера -->
100

<div align="left" style="color:black;padding:10px">
<b>Тестовый пример (lab3.xhtml)</b> <hr/>
<c:forEach var="ss" items="#{testTomee.msgs}"> <h:outputLabel value="#{ss}"/> <hr/>
</c:forEach>
<!-- Часть 3 реализации тестового примера --> Введи текст: <br/>
<h:form>
<h:inputTextarea rows="5" cols="40" value="#{testTomee.text}"/> <br/>
<h:commandButton value="Отправить" action="#{testTomee.addMessage}"/> <hr/>
</h:form>
</div>
</ui:define>
</ui:composition>
</html>
Запуск полной реализации тестового приложения с двумя введенными сообщениями представлен на рисунке 2.25.
Хорошо видно, что с точностью до ряда деталей оформления, прикладная часть тестового JSF-приложения полностью соответствует прикладной части тестового JSP-приложения.
Завершая данный подраздел успешной реализацией тестового приложения, можно достаточно четко сформулировать основные различия между технологиями JSP и JSF.
Технология JSP на первое место выставляет HttpServlet, к которому идут запросы от браузера. Сервлет может сам формировать HTML-страницу или обратиться к соотвествующей JSP-странице. Используя встроенный (неявный) объект out, можно формировать содержимое HTML-страницы, что и было сделано в тестовом примере (см. пункт 1.5.5 главы 1).
Технология JSF на первое место выставляет XHTML-ресурс, к которому обращается браузер, а FacesServlet «работает скрытно», предоставляя каждому запросу браузера объект жизненного цикла (типа Lifecycle) и объект состояния запроса (типа FacesContext).
Предоставляемая браузеру прикладная информация выводится не в страницу, а — в поле страницы.
101