Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Распределенные сервис-ориентированные системы..pdf
Скачиваний:
24
Добавлен:
05.02.2023
Размер:
9.2 Mб
Скачать

6.2 Реализация Web-службы в стиле REST

Web-службы в стиле REST — это всего лишь один из вариантов сетевых программных оболочек, обслуживающих серверные приложения поставщиков сервисов.

Приведенный тезис призван подчеркнуть, что все технологические новинки сервис-ориентированных систем призваны обеспечить удобный и адекватный сервис к достаточно объемным прикладным системам.

В нашей дисциплине, учебной прикладной системой является хранилище записей, содержашее сущности класса Letter. Сама система была представлена как сервисная EJB-компонента в различных видах: как классы Letters и Lets2 (см. листинги 3.4 и 3.24 главы 3), ListLetters (см. листинг 4.4 главы 4) и Lets7 (см. листинг 5.5 главы 5). В данной главе, указанная выше традиция продолжается применительно к технологии RESTful.

Не имея возможности подробно рассмотреть все аспекты технологических возможностей проекта JAX-RS, мы ограничимся демонстрацией следующих решений:

1)преобразуем сущность Letter к виду, достаточному для использования ее стиле REST;

2)создадим EJB-компоненту Lets9, фактически скопировав ее с аналогичной компоненты Lets7;

3)интегрируем EJB-компоненту Lets9 в сервисный класс LetsRestService, обеспечив его необходимым прикладным функционалом;

4)реализуем ряд сервисов из представленного шаблона LetsRestService, ограничиваясь только методами GET и POST для вывода результатов работы сервисов в окно приложения-браузера.

6.2.1 Преобразование сущности Letter

Аннотации сущностей технологии JPA являются совместимыми с аннотациями XML-пред- ставлений технологии JAXB.

Создаем в проекте lab9 класс с именем Letter и заменяем его содержимое на тело аналогичного класса из проекта lab4.

Вносим в текст класса Letter добавления, соответствующие технологии JAXB, как это показано на листинге 6.3.

Обратите внимание, что аннотации @XmlElement ставятся перед публичными методами get*(), а не перед приватными переменными.

249

Листинг 6.3 — Преобразованный класс Letter.java для проекта lab9

package rsos.lab9;

import java.io.Serializable; import java.text.SimpleDateFormat; import java.util.Date;

import javax.persistence.Column; import javax.persistence.Entity;

import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id;

import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType;

import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType;

/**

*Базовая сущность Letter, использующая аннотации

*@Entity и @Table(...).

*Добавляются: обязательная аннотация @XmlRootElement

*и @XmlType(...)

*/

@XmlType(propOrder={"id", "date", "name", "text"}) @XmlRootElement

@Entity

@Table(name = "t_letter")

public class Letter implements Serializable

{

// Идентификатор сериализации

private static final long serialVersionUID = 1L;

@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id;

@Column(nullable = false) @Temporal(TemporalType.TIMESTAMP) private Date date;

private String name; @Column(length = 4096) private String text;

/** * Конструкторы, геттеры, сеттеры и другие бизнес-методы */

public Letter() {}

public Letter(Date date, String name, String text)

{

this.date = date; this.name = name; this.text = text;

}

// Геттеры и сеттеры POJO-класса /**

* Аннотация @XmlElement для публичного метода

250

* getId() */

@XmlElement

public int getId() { return id;

}

public void setId(int id) { this.id = id;

}

/**

*Аннотация @XmlElement для публичного метода

*getDate()

*/

@XmlElement

public Date getDate() { return this.date;

}

public void setDate(Date date) { this.date = date;

}

/**

*Аннотация @XmlElement для публичного метода

*getName()

*/

@XmlElement

public String getName() { return name;

}

public void setName(String name) { this.name = name;

}

/**

*Аннотация @XmlElement для публичного метода

*getText()

*/

@XmlElement

public String getText() { return text;

}

public void setText(String text) { this.text = text;

}

После проведенных изменений, сущность Letter становится способной не только обеспечивать ORM-отображение в таблицу t_letter базы данных lab4db, но и преобразовываться в XML-представление, необходимое для передачи по сети. Следует также помнить, что теперь, перед запуском программ проекта lab9, необходимо стартовать СУБД Apache Derby.

251

6.2.2 Реализация EJB-компоненты Lets9

EJB-компоненты программной платформы Java EE способны инкасулировать менеджеры сущностей и сами инкапсулироваться в сервлеты сервисов RESTful.

Принципиально, RESTful-сервисы могут быть реализованы на основе прямого использования классов сущностей, но следует заметить, что такое решение приемлемо только для очень простых примеров, иначе программное обеспечение сервлетов станет очень громоздким и запутанным. Следует также учесть, что сервис может использовать множество классов сущностей. Это зависит от объема и содержания задач, решаемых приложением.

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

Как уже было отмечено ранее, основную роль в упрощении проектных решений играют аннотации и функционал служебных сервисов, поддерживаемых контейнерами программной платформы Java EE. Сервис EJB-компонент, также играет здесь свою позитивную роль.

Стандартизация программного обеспечения EJB-компонент, применительно к стилю проектирования RESTful, связана с поддержкой этих компонент набором методов, соответствующих набору операций CRUD.

В предыдущей главе, для демонстрации Web-служб SOAP нами использовалась EJB-компонента Lets7, успешно реализующая все необходимые операции CRUD применительно к сущности Letter.

Создадим в проекте lab9 EJB-компоненту с именем Lets9, скопировав исходный текст класса Lets7 и проведя необходимые минимальные изменения, как это показано на листинге 6.4.

Листинг 6.4 — EJB-компонента Lets9.java для проекта lab9

package rsos.lab9; import java.util.List;

import javax.ejb.LocalBean; import javax.ejb.Stateless;

import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.TypedQuery;

import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Root;

252

@Stateless

@LocalBean

public class Lets9

{

//Доступ к контексту менеджера сущностей @PersistenceContext(name = "lab4-unit2") private EntityManager em;

//Получение списка записей таблицы t_letter public List<Letter> getList()

{

//System.out.println("Lets9:getList()...");

//Этап 1. Создаем объект builder CriteriaBuilder builder =

em.getCriteriaBuilder();

// Этап 2. Создаем объект criteria CriteriaQuery<Letter> criteria =

builder.createQuery(Letter.class);

//Этап 3. Создаем объект root Root<Letter> root =

criteria.from(Letter.class);

//Этап 4. Преобразовываем объект criteria,

//включая использование объекта root criteria.select(root);

//Этап 5. Добавляем сортировку

criteria.orderBy(builder.desc(root.get("date")));

//Этап 6. Формируем запрос в виде объекта query TypedQuery<Letter> query = em.createQuery(criteria); //Этап 7. Получаем результат

List<Letter> list = query.getResultList();

//Этап 8. Обрабатываем результат return list;

}

// Получение объекта по ключу public Letter getLetter(int id)

{

Letter l =

em.find(Letter.class, new Integer(id));

return l;

}

//Добавить объект в базу данных public void addLetter(Letter letter) {

em.persist(letter);

}

//Удалить объект из базы данных по ключу

253

public void deleteLetter(int id)

{

//Проверка наличия аргумента вызова Letter letter =

em.find(Letter.class, new Integer(id)); if(letter == null)

return;

//Непосредственное обращение на удаление объекта em.remove(letter);

}

// Модифицировать объект в базе данных public void modLetter(Letter letter) {

if(letter == null) return;

Integer Id = letter.getId();

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());

}

}

Обратите внимание, что мы удалили ненужные для проекта интерфесы, оставив только аннотации:

а) @Stateless и @LocalBean, определяющие EJB-компоненту;

б) @PersistenceContext(...) - для подключения менеджера сущностей технологии JPA.

EJB-компонента Lets9 предоставляет сервис в виде списка объектов типа Letter.

На листинге 6.3, сущность Letter уже преобразована для использования ее технологией JAXB. Теперь необходимо определить структуру объектов, представляющих список объектов типа Letter. Для этой цели введем в проект lab9 новый аннотированный класс с именем ListLets, показанный на листинге 6.5.

Листинг 6.5 — Исходный текст класса ListLets.java проекта lab9

package rsos.lab9;

import java.io.Serializable; import java.util.ArrayList; import java.util.List;

import javax.xml.bind.annotation.XmlElement;

254