
- •Введение
- •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
- •Вопросы для самопроверки
- •Заключение
- •Список использованных источников
- •Алфавитный указатель

Рисунок 6.17 — Результат работы метода mPostLetter()
Чтобы новое сообщение появилось в общем списке, необходимо активировать кнопку «GET-список».
6.3.6 Клиент, реализующий методы DELETE и PUT
Реализация метода mDeleteLetter() во многом похожа на реализацию метода mGetLetter(), поскольку при формировании адреса запроса, кроме переменной address используется также переменная id. Кроме того, необходимо реализовать анализ трех кодов возврата:
а) если код возврата равен 200, то объект типа Response содержит удаленный объект и его необходимо извлечь, как описано ниже;
б) если код возврата равен 202, то действие по удалению объекта принято к исполнению, но еще не завершилось;
в) если код возврата равен 204, то адресуемый объект — удален, но в ответе его тело отсутствует;
При получении кода возврата 200, из объекта типа Response извлекается объект типа Letter, а затем — из объекта типа Letter извлекаются и устанавливаются переменные id и text.
Описанная реализация метода mDeleteLetter() показана на листинге 6.20.
288
Листинг 6.20 — Реализация метода mDeleteLetter() компоненты Lab9
// Удалить объект типа Letter по идентификатору id public String mDeleteLetter() {
//Проверяем авторизацию if(!isAuth()) {
resMsg = "Метод DELETE - нет авторизации!"; return "lab9";
}
//Формируем запрос к сервису
WebTarget target = ClientBuilder.newClient()
.target(this.address)
.path(new Integer(id).toString()); Invocation invocation =
target.request()
.buildDelete();
//Отправка запроса и получение ответа Response response =
invocation.invoke();
//Проверка кода возврата
int status = response.getStatus(); if(status == 202) {
resMsg = "Метод DELETE - код возврата: "
+new Integer(status).toString()
+" - Запрос с id="
+new Integer(id).toString()
+" - принят к исполнению...";
return "lab9";
}
if(status == 204) {
resMsg = "Метод DELETE - код возврата: "
+new Integer(status).toString()
+" - Отсутствует объект запроса с id="
+new Integer(id).toString();
return "lab9";
}
if(status != 200) {
resMsg = "Метод DELETE - код возврата: "
+ new Integer(status).toString() + "!"; return "lab9";
}
resMsg = "Метод DELETE - код возврата: 200 - Хорошо";
//Извлечение тела ответа в виде объекта типа Letter Letter body =
response.readEntity(Letter.class);
//Извлекаем id, text и возвращаемся к lab9.xhtml id = body.getId();
text = body.getText(); return "lab9";
}
289

Для удаления записи необходимо ввести ее идентификатор и активировать кнопку «DELETE-письмо». Результат удаления записи с id=106 показан на рисунке 6.18.
Рисунок 6.18 — Результат удаления записи методом mDeleteLetter()
Теперь перейдем к реализации метода mPutLetter().
Реализация метода mPutLetter() во многом похожа на реализацию метода mPostLetter(), поскольку в обоих случаях осуществляется передача объекта типа Letter производителю сервиса. Что касается кодов статуса объекта типа Response, то их — всего два:
1)код 200 — Хорошо, если в теле ответа возвращен измененный объект;
2)код 204 — Нет содержимого, если изменений не произошло.
При указанных условиях и ограичениях, описанная выше реализация метода mPutLetter() представлена на листинге 6.21.
290
Листинг 6.21 — Реализация метода mPutLetter() компоненты Lab9
// Модифицировать объект типа Letter по идентификатору id public String mPutLetter() {
//Проверяем авторизацию if(!isAuth()) {
resMsg = "Метод PUT - нет авторизации!"; return "lab9";
}
//Создаем новый объект типа Letter
Letter letter =
new Letter(new Date(), rsos.getUser(), text); letter.setId(id);
// Формируем запрос к сервису
WebTarget target = ClientBuilder.newClient()
.target(this.address)
.register(Letter.class); Invocation invocation =
target.request(MediaType.APPLICATION_XHTML_XML)
.buildPut(Entity.entity(letter, MediaType.APPLICATION_XML_TYPE));
//Отправка запроса и получение ответа Response response =
invocation.invoke();
//Проверка кода возврата
int status = response.getStatus(); if(status == 204) {
resMsg = "Метод PUT - код возврата: "
+new Integer(status).toString()
+" - Нет содержимого";
return "lab9";
}
if(status != 200) {
resMsg = "Метод PUT - код возврата: "
+ new Integer(status).toString() + "!"; return "lab9";
}
resMsg = "Метод PUT - код возврата: 200 - Хорошо";
//Извлечение тела ответа в виде объекта типа Letter Letter body =
response.readEntity(Letter.class);
//Извлекаем id, text и возвращаемся к lab9.xhtml id = body.getId();
text = body.getText(); return "lab9";
}
Результат модификации записи с id=109 показан на рисунке 6.19.
291

Рисунок 6.19 — Результат модификации записи методом mPutLetter()
Обратите внимание, что после обновления записи и, если оно прошло успешно, то обновленный вариант переписывается в форму, а список всех записей остается неизменным. Чтобы изменить список всех записей, необходимо активировать кнопку «PUT-письмо».
Данным примером, мы завершаем изучение учебного материала данной главы и дисциплины в целом. Надеюсь, что полученные в процессе обучения навыки и знания обеспечат дальнейший профессиональный рост студентов.
292