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

4.2 Технология JSON

Частов качестве альтернативы XML-формату, при взаимодействии распределенных приложений предлагается использовать формат JSON.

JSON (JavaScript Object Notation) — текстовый формат обмена данными, основанный на языке JavaScript. Был разработан Дугласом Крокфордом в начале 2000-х годов.

Основная идея этого формата — упростить представление данных для несложных объектов и сделать его более наглядным по сравнению с форматами, основанными на языке XML. Его возможности весьма ограничены следующими типами представлений:

а) примитивными типами: число, строка, двоичное значение и null; б) двумя структурными типами: объекты и массивы.

Основные понятия этого формата отображены в таблице 4.3.

Таблица 4.3 — Основные понятия формата представления JSON [17]

Понятие

Описание

Число

Десятичное представление, как в языке Java. Восьмеричные и шестнадцате-

 

ричные значения не используются.

Строка

Последовательность из нуля или более символов Unicode, ограниченная

 

двойными кавычками и использующая для экранирования символ обратного

 

слеша.

Значение

Представлено в одном из следующих форматов: строка в двойных кавычках,

 

число, двоичное значение, объект или массив.

Массив

Упорядоченный набор значений, заключенный в квадратные скобки, обозна-

 

чающие начало и конец массива. Значения массива разделены запятыми и

 

могут быть объектами.

Объект

Это — неупорядоченный набор пар «имя/значение», разделенных запятыми

 

и заключенный в фигурные, которые обозначают начало и конец объекта.

 

Пары «имя/значение» соответствуют атрибутам POJO-классов в языке Java.

ВWeb-технологиях, официальный тип содержимого представления JSON

application/json, а расширение имен файлов — .json.

Для языка Java имеется собственная спецификация JSR 353, которая полностью реализована, начиная с программной платформы Java EE 7, и имеет обозначение API, как JSON-P.

В настоящее время технология JSON является достаточно популярной. Для не на языке Java разработано множество различных инструментов, например, JSON-Lib, fastjson, Flexjson, Jettison, Jackson и другие. Мы, в данном подразделе, рассмотрим только основы этой технологии, входящей в официаль-

188

ное программное обеспечение платформы Java EE.

4.2.1 Программное обеспечение технологии JSON

Основные пакеты JSON-P, обслуживающие технологию JSON, представлены в таблице 4.4.

 

Таблица 4.4 — Основные пакеты API JSON-P [17]

Пакет

Описание пакета

javax.json

Предоставляет API для описания структуры данных JSON, таких

 

как: класс JsonArray для массива JSON и класс JsonObject для

 

объекта JSON. Предоставляет точку входа для анализа,

 

построения, чтения и записи объектов и массивов JSON с

 

помощью потоков.

javax.json.spi

Интерфейс провайдера служб (Service Provider Interface),

 

предназначенный для подключения классов, таких как JsonParser и

 

JsonGenerator.

javax.json.stream

Предоставляет потоковый API для анализа и генерации JSON.

Основной API рассматриваемой технологии опирается на базовый класс javax.json.Json. Он содержит методы для создания объектов следующего набора типов:

1.JsonParser — класс для обеспечения потокового анализа JSON-докумен- та с использованием сигналов. Создается методом createParser(...) на потоке чтения JSON-документа.

2.JsonGenerator — класс для создания JSON-документа. Создается методом createGenerator(...) на потоке вывода информации.

3.JsonWriter — класс для создания потока вывода JSON-документа.

4.JsonReader — класс для создания потока ввода JSON-документа.

5.JsonObjectBuilder — класс для создания объекта при построении JSONдокумента. Сам создается методом createObjectBuilder(...).

6.JsonArrayBuilder — класс для создания массивов при построении JSONдокумента. Сам создается методом createArrayBuilder(...).

Представление JAVA-объектов в формате JSON требует хорошего знания структуры этих объектов.

Действительно, если технология JAXB использует аннотации, которые устанавливаются перед полями или соответствующими методами класса и, далее, сами преобразования осуществляются автоматически, то технология JSON

189

требует явного описания программистом всех переменных и имен объектов этих классов. И, чтобы не быть голословными, проведем JSON-представление результата работы программы Test4 проекта lab5, которое сохранено в файле lab5.ListLetters.xml и показано ранее на рисунке 4.4. Результат такого представления показан на листинге 4.6.

Листинг 4.5 — JSON-представление текста из файла lab5.ListLetters.xml

{

"listLetters":{

"name":"Список писем для приложения lab5:Test3", "list-letters":[

{

"list":{

"id":21, "date":"2020-09-06T09:53:25.766+07:00", "name":"upk",

"text":"Сообщение №21 для lab5:Test3"

}

},

{

"list":{

"id":22, "date":"2020-09-06T09:53:25.766+07:00", "name":"asu",

"text":"Сообщение №22 для lab5:Test3"

}

}

]

}

}

Необходимо иметь достаточно хорошее программистское воображение, чтобы определить в таком достаточно примитивном представлении объекты классов ListLetters и Letter. Кроме того, возникнут неприятные проблемы с преобразованием переменной date, поскольку программное обеспечение JSON- P не имеет средств для работы с форматом даты.

Если предположить, что в работе используются классы Java с более сложной структурой и большей вложенностью дочерних классов, то привлекательность формата JSON уже не будет столь очевидной.

Для анализа структуры JSON-представлений можно использовать объекты класса Parser, которые обеспечивают потоковую обработку информации. Мы такой подход использовать не будем, а обратим внимание на прямое извлечение информации из JSON-документов. Оно обеспечивается двумя классами:

1.JsonObject — класс для извлечения представления объекта из входного потока или из объекта того же класса JsonObject, используя указание имени объекта.

2.JsonArray — класс для представления массива объектов, извлекаемое из

190

объектов класса JsonObject.

Каким образом — это делается? Рассмотрим на конкретных примерах.

4.2.2 Преобразование объекта Java в документ JSON

Продемонстрируем возможности программного обеспечения JSON-P, реализовав представление объекта класса ListLetters в формат JSON, как это представлено на листинге 4.5, внеся следующие корректировки и дополнения:

а) дату класса Letter будем отображать числом типа Long;

б) пример преобразования реализуем в новом проекте lab6 типа Dynamic Web Project, чтобы подключить программное обеспечение сервера приложений TomEE, содержащее инструменты пакета JSON-P;

в) приложение назовем Test1;

г) результат преобразования сохраним в файле $HOME/lab6.Test1.json; д) для преобразования воспользуемся методами класса JsonObjectBuilder.

Результат реализации приложения Test1 представлен на листинге 4.6.

Листинг 4.6 — Исходный текст приложения Test1.java проекта lab6

package rsos.lab6;

import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.Date;

import javax.json.Json; import javax.json.JsonObject;

import javax.json.JsonObjectBuilder;

public class Test1

{

public static void main(String[] args) throws IOException

{

// Создание основного инструментального объекта JsonObjectBuilder job =

Json.createObjectBuilder();

//Преобразование текущей даты в тип Long Long tt =

new Date().getTime();

//Представление типа Long в виде строки String ss =

tt.toString();

//Формирование представления согласно листинга 4.5 JsonObject obj =

job.add("listLetters", Json.createObjectBuilder()

.add("name", "Список писем для приложения lab5:Test3")

.add("list-letters", Json.createArrayBuilder()

.add(Json.createObjectBuilder()

191

.add("list", Json.createObjectBuilder()

.add("id", 21)

.add("date", ss)

.add("name", "upk")

.add("text", "Сообщение №21 для lab5:Test3")))

.add(Json.createObjectBuilder()

.add("list", Json.createObjectBuilder()

.add("id", 22)

.add("date", ss)

.add("name", "asu")

.add("text", "Сообщение №22 для lab5:Test3")))))

.build();

//Открытие потока вывода в файл FileWriter writer =

new FileWriter(new File(System.getenv("HOME" )

+"/lab6.Test1.json"));

//Запись результата в файл

writer.write(obj.toString()); writer.close();

}

}

Запустив приложение Test1 на выполнение, мы получим заявленный файл $HOME/lab6.Test1.json с содержимым, показанным на рисунке 4.5.

Рисунок 4.5 — Результат работы приложения Test1 проекта lab6

Хорошо видно, что результат работы программы Test1 представляет собой неформатированную текстовую строку, но даже в таком виде ее можно вполне корректно сопоставить с текстом исходного листинг 4.5. При более сложном объекте представления, например, при десяти записях объектов класса Letter, сопоставление таких представлений вызывало бы серьезные проблемы.

Потребитель представления в формате JSON должен адекватно выполнять обратное преобразование.

Теперь рассмотрим обратное преобразование текущего содержимого файла $HOME/lab6.Test1.json в объект класса ListLetters. Для этого:

192

1)создадим в проекте lab6 классы Letter и ListLetters, позаимствовав их сожержимое из проекта lab5; аннотации из классов можно убрать;

2)создадим приложение Test2, приведенное на листинге 4.7, которое извлекает информацию из файла результата приложения Test1 и создает объект класса ListLetters.

Листинг 4.7 — Исходный текст приложения Test2.java проекта lab6

package rsos.lab6;

import java.io.FileNotFoundException; import java.io.FileReader;

import java.util.ArrayList; import java.util.Date; import java.util.List; import javax.json.Json; import javax.json.JsonArray;

import javax.json.JsonObject; import javax.json.JsonReader; import javax.json.JsonValue;

public class Test2

{

public static void main(String[] args) throws FileNotFoundException

{

//Открываем файл для чтения JsonReader reader =

Json.createReader(new FileReader(System.getenv("HOME" )

+"/lab6.Test1.json"));

//Читаем содержимое файла в объект класса JsonObject JsonObject obj =

reader.readObject(); reader.close();

//Выделяем корневой класс и приступаем к созданию объекта obj =

obj.getJsonObject("listLetters");

//Создаем целевой объект

ListLetters listlets =

new ListLetters(obj.getString("name"));

//Выделяем объекты массива JsonArray array =

obj.getJsonArray("list-letters");

//Создаем пустой список

List<Letter> list =

new ArrayList<>();

// Рабочие переменные Letter let;

Long ll;

193