Чтение JSON

Этот раздел перенесён из документации Camunda 7 и в дальнейшем будет доработан с учётом особенностей OpenBPM Engine

Формат данных JSON поддерживает чтение JSON из строк (String) и объектов Reader.

Чтение JSON из строки

import static io.openbpm.spin.Spin.*;
import static io.openbpm.spin.DataFormats.*;

SpinJsonNode json = S("{\"customer\": \"Kermit\"}", json());

Второй параметр json() подсказывает Spin использовать формат данных JSON для разбора строки.

Альтернативно, можно напрямую использовать функцию JSON(…​):

import static io.openbpm.spin.Spin.*;

SpinJsonNode json = JSON("{\"customer\": \"Kermit\"}");

Строки, представляющие примитивные JSON-значения, также можно читать. Например, JSON("true") возвращает SpinJsonNode, представляющий булевое значение true.

Чтение JSON из Reader

Spin также поддерживает чтение JSON из экземпляра java.io.Reader:

import static io.openbpm.spin.Spin.*;
import static io.openbpm.spin.DataFormats.*;

SpinJsonNode json = S(reader, json());

Метод JSON(…​) также поддерживает объекты Reader. Следующий пример показывает, как читать JSON из файла (обработка ошибок опущена):

import static io.openbpm.spin.Spin.*;

FileInputStream fis = new FileInputStream("/tmp/customer.json");
InputStreamReader reader = new InputStreamReader(fis, "utf-8");
SpinJsonNode json = JSON(reader);

Чтение JSON с использованием скриптового языка

JSON можно читать из скриптовых языков так же, как из Java. Поскольку скриптовые языки используют динамическую типизацию, указывать формат данных не нужно — можно использовать автоопределение. Следующий пример демонстрирует чтение JSON на JavaScript:

var customer = S('{"customer": "Kermit"}');

Чтение свойств JSON

Для получения свойств из JSON-дерева используется метод .prop("name"). Он возвращает свойство в виде SpinJsonNode, из которого можно извлечь значение, как показано в следующих примерах.

На Java:

import static io.openbpm.spin.Spin.*;

SpinJsonNode json = JSON("{\"customer\": \"Kermit\"}");
SpinJsonNode customerProperty = json.prop("customer");
String customerName = customerProperty.stringValue();

На JavaScript:

var json = S('{"customer": "Kermit"}');
var customerProperty = json.prop("customer");
var customerName = customerProperty.value();

Типы значений

Метод SpinJsonNode#value() возвращает Java-эквивалент строкового, булевого, числового или null JSON-свойства. Для свойств типа Object и Array он выбрасывает исключение. Также доступны следующие методы:

  • #stringValue() — возвращает Java String-представление значения или выбрасывает исключение, если значение не является строкой

  • #numberValue() — возвращает Java Number-представление значения или выбрасывает исключение, если значение не является числом

  • #boolValue() — возвращает Java Boolean-представление значения или выбрасывает исключение, если значение не является булевым

Проверка типа значения свойства

  1. isObject() — возвращает boolean

  2. hasProp() — возвращает boolean

  3. isBoolean() — возвращает boolean

  4. isNumber() — возвращает boolean

  5. isString() — возвращает boolean

  6. isNull() — возвращает boolean

  7. isValue() — возвращает boolean

  8. isArray() — возвращает boolean

Пример на JavaScript:

var json = S('{"over18":false}');
json.prop('over18').isBoolean() //returns true

Получение массива данных

Если свойство является массивом, можно получить список его элементов.

На Java:

import static io.openbpm.spin.Spin.*;

SpinJsonNode json = JSON("{\"customer\": \[\"Kermit\", \"Waldo\"\]}");
SpinJsonNode customerProperty = json.prop("customer");
SpinList customers = customerProperty.elements();
SpinJsonNode customer = customers.get(0);
String customerName = customer.stringValue();

На JavaScript:

var json = S('{"customer": ["Kermit", "Waldo"]}');
var customerProperty = json.prop("customer");
var customers = customerProperty.elements();
var customer = customers.get(0)
var customerName = customer.value();

Получение имён полей

Метод .fieldNames() позволяет получить имена всех дочерних узлов и свойств узла. Следующий пример показывает, как использовать .fieldNames() в Java и JavaScript.

На Java:

import static io.openbpm.spin.Spin.*;

SpinJsonNode json = JSON("{\"customer\": \[\"Kermit\", \"Waldo\"\]}");
ArrayList fieldNames = json.fieldNames();
String fieldName1 = fieldNames.get(0)

На JavaScript:

var json = S('{"customer": ["Kermit", "Waldo"]}');
var fieldNames = json.fieldNames();
var fieldName1 = fieldNames.get(0)

Установка свойств JSON

Для установки свойства используется метод .prop("name", object). Он позволяет задать одно из следующих 5 простых типов:

  • String — пример: .prop("name", "Waldo")

  • Integer — пример: .prop("age", 42)

  • Long — пример: .prop("period", 4200000000)

  • Float — пример: .prop("price", 42.00)

  • Boolean — пример: .prop("active", true)

или один из 2 контейнерных типов:

  • Array — может содержать произвольное количество простых и контейнерных типов

    Пример на Java:

    import static io.openbpm.spin.Spin.*;
    
    SpinJsonNode json = JSON("{\"customer\": \[\"Kermit\", \"Waldo\"\]}");
    ArrayList<Object> list = new ArrayList<Object>();
    list.add("new entry");
    list.add("new entry2");
    json.prop("new_array", list);

    Пример на JavaScript:

    var json = S('{"customer": ["Kermit", "Waldo"]}');
    var list = ["new entry", "new entry2"];
    json.prop("new_array", list);
  • Object — может содержать произвольное количество простых и контейнерных типов

    Пример на Java:

    import static io.openbpm.spin.Spin.*;
    
    SpinJsonNode json = JSON("{\"customer\": \[\"Kermit\", \"Waldo\"\]}");
    Map<String, Object> object = new HashMap<String, Object>();
    object.put("new_entry", 42);
    object.put("new_entry2", "Yeah!");
    json.prop("new_object", object);

    Пример на JavaScript:

    var json = S('{"customer": ["Kermit", "Waldo"]}');
    var object = {
      "new_entry": 1,
      "new_entry2": "Yeah!"
    };
    json.prop("new_array", object);

Удаление свойств JSON

Существует два способа удаления свойств из JSON-объекта:

  • .deleteProp("name") — удаляет свойство с указанным именем

  • .deleteProp(<список имён>) — удаляет одно или несколько свойств с указанными именами

Подробнее см. следующие примеры для JavaScript и Java.

Java:

import static io.openbpm.spin.Spin.*;

SpinJsonNode json = JSON("{\"customer\": \"Kermit\", \"language\": \"en\"}");
List<String> listOfNames = new ArrayList<String>();
listOfNames.add("customer");
listOfNames.add("language");

// удаляет только свойство customer
json.deleteProp("customer");

// удаляет customer и language
json.deleteProp(list);

JavaScript:

var json = S('{"customer": ["Kermit", "Waldo"], "language": "en"}');
var list = ["customer", "en"];

// удаляет только свойство customer
json.deleteProp("customer");

// удаляет customer и language
json.deleteProp(list);

Работа с JSON-массивами

JSON-массивы представляют собой список объектов. Spin предоставляет следующие методы для работы с таким списком:

  • .indexOf(<Object>) — возвращает индекс ПЕРВОГО вхождения искомого объекта

  • .lastIndexOf(<Object>) — возвращает индекс ПОСЛЕДНЕГО вхождения искомого объекта

  • .append(<Object>) — добавляет объект в конец списка

  • .insertAt(<Index>, <Object>) — вставляет объект по указанному индексу

  • .insertBefore(<Search object>, <Object>) — вставляет объект перед ПЕРВЫМ вхождением другого объекта

  • .insertAfter(<Search object>, <Object>) — вставляет объект после ПЕРВОГО вхождения другого объекта

  • .remove(<Object>) — удаляет ПЕРВОЕ вхождение объекта

  • .removeLast(<Object>) — удаляет ПОСЛЕДНЕЕ вхождение объекта

  • .removeAt(Index) — удаляет элемент списка по указанному индексу

Эти методы позволяют быстро работать с JSON-массивами. Для демонстрации будем использовать следующий JSON-объект:

{
  "test-array" : [
    "testdata1",
    "testdata2",
    1,
    2,
    true,
    1,
    false,
    1
  ]
}

Пример 1 — Получение индекса 'testdata2' и последнего вхождения '1'

import static io.openbpm.spin.Spin.*;

SpinJsonNode json = JSON("{\"test-array\" : [\"testdata1\",\"testdata2\",1,2,true,1,false,1]}");
SpinJsonNode list = json.prop("test-array");

Integer i = list.indexOf("testdata2"); // должно быть '1'
Integer j = list.lastIndexOf(1); // должно быть '7'
var json = S('{"test-array" : ["testdata1","testdata2",1,2,true,1,false,1]}');
var list = json.prop("test-array");

var i = list.indexOf("testdata2"); // должно быть 1
var j = list.lastIndexOf(1); // должно быть '7'

Пример 2 — Добавление и удаление данных в списке

import static io.openbpm.spin.Spin.*;

SpinJsonNode json = JSON("{\"test-array\" : [\"testdata1\",\"testdata2\",1,2,true,1,false,1]}");
SpinJsonNode list = json.prop("test-array");

list.append("test2"); // в конце списка теперь находится "test2"
list.remove("test2"); // и теперь его нет ;)

list.insertAt(1, "test3"); // test3 вставлен перед testdata2
list.removeAt(1, "test3"); // и теперь его нет ;)

list.insertBefore(true, "test4"); // теперь test4 находится на индексе 4
list.insertAfter(true, 5); // теперь 5 находится на индексе 6
var json = S('{"test-array" : ["testdata1","testdata2",1,2,true,1,false,1]}');
var list = json.prop("test-array");

list.append("test2"); // в конце списка теперь находится "test2"
list.remove("test2"); // и теперь его нет ;)

list.insertAt(1, "test3"); // test3 вставлен перед testdata2
list.removeAt(1, "test3"); // и теперь его нет ;)

list.insertBefore(true, "test4"); // теперь test4 находится на индексе 4
list.insertAfter(true, 5); // теперь 5 находится на индексе 6

Лицензия и атрибуция

Эта документация была создана на базе материала "Camunda 7 Docs" от Camunda, находится под лицензией Creative Commons Attribution-ShareAlike 3.0 Unported License .

Оригинал документации: https://docs.camunda.org