- •Введение
- •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
- •Вопросы для самопроверки
- •Заключение
- •Список использованных источников
- •Алфавитный указатель
Letter l = em.find(Letter.class, Id);
if(l == null) return;
//System.out.println("Letters: модифицирую №" + Id); l.setDate(letter.getDate()); l.setName(letter.getName()); l.setText(letter.getText());
}
}
При анализе данного листинга следует обратить внимание на способ инкапсуляции объекта менеджера сущностей em со ссылкой на юнит «lab4-unit2» (выделено серым цветом). В результате не нужно использовать ни фаб-рику менеджеров ни менеджер транзакций.
Самым сложным в реализации является метод getList(), но он полностью комментирован по этапам реализации Criteria-запросов, описанных в предыдущем пункте. Дабавлена также сортировка по атрибуту date.
Следует обратить внимание и на метод modLetter(...), модифицирующий уже существующий объект базы данных:
1)сначала, из представленного в качестве аргумента объекта извлекается ключ модифицеруемой записи (объекта);
2)затем, модифицируемый объект извлекается из базы данных;
3)наконец, переустанавливаются атрибуты извлеченного объекта и — все; далее, менеджер сущностей сам обеспечит модификацию объекта.
3.3.3 Реализация JPA-сервлета
Для получения полноценного демонстрационного примера, необходимо реализовать соответсвующий HTTP-сервлет и JSP-страницу.
Проведем реализацию сервлета JpaServlet2, инкапсулирующего EJBкомпоненту Lets2 и обеспечивающего полную функциональность учебной задачи Letters (Письма), ранее заявленной в пункте 3.1.1. Для этого, сначала реализуем новую JSP-страницу в файле jpa_test2.jsp, исходный текст которой представлен на листинге 3.25.
Листинг 3.25 — Исходный текст JSP-страницы jpa_test2.jsp проекта lab4
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
167
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<jsp:useBean id="letter2" class="rsos.lab4.Letter" scope="page" />
<html> <head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>lab4</title>
</head> <body>
<hr>
<b>Тестовая страница проекта lab4 (jpa_test2.jsp)</b>
<hr>
<table id="table1" cellspacing="0" cellpadding="5" border="0" > <thead><tr>
<th align="left" >№</th> <th align="left" >Дата</th>
<th align="left" >Пользователь</th> <th align="left" >Сообщение</th>
</tr></thead> |
|
<tbody> |
|
<c:forEach items="${lists2}" var="letter2"> |
|
<tr> |
|
<td width="8"> |
|
<c:out value="${letter2.id}" default="*" |
/></td> |
<td width="8"> |
|
<c:out value="${letter2.dateString}" default="Нет даты" |
/></td> |
<td width="8">
<c:out value="${letter2.name}" default="Нет пользователя"/></td> <td>
<c:out value="${letter2.text}" default="Нет текста..." /></td> </tr>
</c:forEach>
</tbody> </table>
<hr>
<form action="JpaServlet2" method="post" accept-charset="UTF-8"> <table id="table2">
<tr>
<td>Номер сообщения: </td>
<td><input type="text" size="6" name="id" value="${id}" /></td>
</tr> <tr>
<td>Имя пользователя: </td>
<td><input type="text" size="40" name="user" value="${user}" /></td>
</tr> <tr>
<td>Новый текст: </td>
<td><textarea rows="5" cols="40" name="text">
<%= request.getAttribute("text") %> </textarea></td>
</tr>
168
</table>
<hr>
Состояние запроса (<b><i><%= request.getAttribute("action")%></i></b>): <b><i><%= request.getAttribute("state") %></i></b>
<hr>
<table id="table3"> <tr>
<td>
<input type="radio" name="action" value="list" checked="checked"> Обновить
</td>
<td><input type="submit" value="Отправить запрос" /> </td>
</tr> <tr>
<td>
<input type="radio" name="action" value="add"> Добавить<br>
<input type="radio" name="action" value="get"> Прочитать по номеру<br>
<input type="radio" name="action" value="delete"> Удалить по номеру<br>
<input type="radio" name="action" value="mod"> Модифицировать по номеру<br>
</td>
</tr> </table> </form> <hr>
</body> </html>
Наиболее важные места представленного листинга, которые должны быть учтены в сервлете JpaServlet2, выделены серым фоном.
Что касается самого сервлета JpaServlet2, то его общая структура совпадает с предыдущей реализацией. Отличия состоят в инкасуляции нового EJBкомпонента Lets2 и реализации всех запросов, что показано на листинге 3.26. Измененные места также выделены серым фоном.
Листинг 3.26 — Исходный текст сервлета JpaServlet2 проекта lab4
package rsos.lab4;
import java.io.IOException; import java.util.Date; import javax.ejb.EJB;
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class JpaServlet2
169
*/ @WebServlet("/JpaServlet2")
public class JpaServlet2 extends HttpServlet
{
private static final long serialVersionUID = 1L;
// Инкапсуляция EJB-компонента типа Lets2 @EJB
private Lets2 lets2; // EJB-компонент
/** * Конструктор */
public JpaServlet2() {
/**
* Метод doGet(...) */
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
// Переходим к методу doPost() doPost(request, response);
}
/**
* Метод doPost(...) */
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
/**
*Явная установка кодировок объектов запроса и ответа.
*Стандартная установка контекста ответа.
*/
response.setCharacterEncoding("UTF-8"); response.setContentType("text/html"); request.setCharacterEncoding("UTF-8");
// Начальные значения |
||
String |
state |
= "<b>Нормально...</b>"; |
String |
action |
= request.getParameter("action"); |
String |
sId |
= request.getParameter("id"); |
Integer |
Id |
= ToInt.get(sId); |
String |
user |
= request.getParameter("user"); |
String |
text |
= request.getParameter("text"); |
if(action == null) action |
= "list"; |
|||
if(user |
== null) user |
= "asu"; |
||
if(user.trim().length() == 0) |
user = "asu"; |
|||
if(text |
== null) text |
= |
""; |
|
request.setAttribute("state", state);
// Действия if("add".equals(action)) {
170
lets2.addLetter(new Letter(new Date(), user, text)); text = "";
}
if("get".equals(action)) { if(Id == null) {
request.setAttribute("state",
"<b>Ошибочный идектификатор сообщения...</b>"); text = "";
} else {
Letter letter = lets2.getLetter(Id.intValue());
if(letter == null) { request.setAttribute("state",
"<b>Нет такого сообщения...</b>"); text = "";
} else {
user = letter.getName(); text = letter.getText();
}
}
}
if("delete".equals(action)) { if(Id == null) {
request.setAttribute("state",
"<b>Ошибочный идектификатор сообщения...</b>"); text = "";
} else { lets2.deleteLetter(Id.intValue()); text = "";
}
}
if("mod".equals(action)) { if(Id == null) {
request.setAttribute("state",
"<b>Ошибочный идектификатор сообщения...</b>"); } else {
Letter l =
new Letter(new Date(), user, text); l.setId(Id.intValue()); lets2.modLetter(l);
}
}
request.setAttribute("lists2", lets2.getList());
// Установка атрибутов request.setAttribute("action", action); request.setAttribute("id", sId); request.setAttribute("user", user); request.setAttribute("text", text.trim()); /**
* Стандартное подключение ресурса JSP-страницы */
request.getRequestDispatcher("/WEB-INF/jpa_test2.jsp")
171
.forward(request, response);
}
}
Результат запуска сервлета JpaServlet2 показан на рисунке 3.7. Хорошо видно, что этот результат полностью совпадает с запуском JpaServlet1, представленным ранее на рисунке 3.6.
Рисунок 3.7 — Результат запуска сервлета JpaServlet2
Продолжая тестирование, выполним два действия:
1)добавим текст: «Тест сервлета JpaServlet2.»;
2)удалим, например, запись №2.
Врезультате мы получим измененный список содержимого базы данных, показанный на рисунке 3.8. Дополнительно, нужно проверить результат изменения базы данных запустив SQL-сценарий select_lab4db.sql.
Обратите также внимание, что список записей отсортирован по убыванию
172
даты внесения изменений, как это сделано — смотрите метод getList() EJBкомпонента Lets2, представленного ранее на листинге 3.24.
Рисунок 3.8 — Результат работы сервлета, после проведенных изменений
В завершение данной главы отметим, что мы с вами кратко изучили теорию и практику создания EJB-компонент программной платформы Java EE, которые обычно всегда работают с теми или иными базами данных. В плане общего контекста изучаемой дисциплины, EJB-компоненты являются важной частью распределнных сервис-ориентированных систем и рассматриваются в них как распределенные приложения.
Хотя все практические результаты получены в среде Web-серверов, это не умаляет результаты полученных студентом знаний. В дальнейшем, теоретическая и практическая части данной главы будут использованы в учебном материале последующих глав.
173
