Рубрики
Без рубрики

Сериализация Гипермедиа С помощью JSON-LD

Узнайте, как сериализовать и десериализовать JSON-LD с помощью Jackson.

Автор оригинала: baeldung.

1. Обзор

JSON-LD – это формат на основе JSON RDF для представления Связанных данных . Это позволяет расширить существующие объекты JSON с помощью возможностей гипермедиа; другими словами, возможность содержать ссылки машиночитаемым способом.

В этом уроке мы рассмотрим несколько вариантов на основе Джексона для сериализации и десериализации формата JSON-LD непосредственно в POJOs . Мы также рассмотрим основные концепции JSON-LD, которые позволят нам понять примеры.

2. Основные Понятия

В первый раз, когда мы видим документ JSON-LD, мы замечаем, что некоторые имена членов начинаются с символа @ . Это ключевые слова JSON-LD, и их значения помогают нам понять остальную часть документа.

Чтобы ориентироваться в мире JSON-LD и понять этот учебник, нам нужно знать четыре ключевых слова:

  • @context – это описание объекта JSON, содержащее карту ключ-значение всего, что необходимо для интерпретации документа
  • @vocab – это возможный ключ в @context , который вводит словарь по умолчанию, чтобы сделать объект @context намного короче
  • @id – это ключевое слово для идентификации ссылок либо как свойство ресурса, представляющее прямую ссылку на сам ресурс, либо как значение @type для обозначения любого поля в качестве ссылки
  • @type – ключевое слово для идентификации типов ресурсов либо на уровне ресурсов, либо в контексте @ ; например, для определения типа встроенных ресурсов

3. Сериализация в Java

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

Будучи уже знакомыми с Джексоном, мы могли бы понять, что мы могли бы легко сериализовать два пользовательских поля в любом POJO как @id и @type , используя аннотацию @JsonProperty . Однако написание @контекста вручную может быть большой работой, а также подвержено ошибкам .

Поэтому, чтобы избежать этого подверженного ошибкам подхода, давайте подробнее рассмотрим две библиотеки, которые мы могли бы использовать для @context generation. К сожалению, ни один из них не способен генерировать все функции JSON-LD, но мы также рассмотрим их недостатки позже.

4. Сериализация С Помощью Jackson-Json ld

Джексон-Джсон лд это модуль Джексона, который позволяет аннотировать POJOS удобным способом для создания документов JSON-LD.

4.1. Зависимости Maven

Во-первых, давайте добавим jackson-json ld в качестве зависимости к pom.xml :


    com.io-informatics.oss
    jackson-jsonld
    0.1.1

4.2. Пример

Затем давайте создадим наш пример POJO и аннотируем его для @context generation:

@JsonldResource
@JsonldNamespace(name = "s", uri = "http://schema.org/")
@JsonldType("s:Person")
@JsonldLink(rel = "s:knows", name = "knows", href = "http://example.com/person/2345")
public class Person {
    @JsonldId
    private String id;
    @JsonldProperty("s:name")
    private String name;

    // constructor, getters, setters
}

Давайте разберем шаги, чтобы понять, что мы сделали:

  • С помощью @JsonldResource мы отметили POJO для обработки как ресурс JSON-LD
  • В @JsonldNamespace мы определили стенографию для словаря, который мы хотим использовать
  • Параметр, указанный в @JsonldType , станет @type ресурса
  • Мы использовали аннотацию @JsonldLink для добавления ссылок на ресурс. При обработке параметр name будет использоваться в качестве имени поля, а также добавлен в качестве ключа в контекст @. |/href будет значением поля, а rel будет отображенным значением в контексте @ Поле, которое мы отметили
  • @JsonldId , станет @ideal ресурса Параметр, указанный в
  • @JsonldProperty , станет значением, сопоставленным имени поля в контексте @

Далее, давайте сгенерируем документ JSON-LD.

Во-первых, мы должны зарегистрировать модуль Json ld в ObjectMapper . Этот модуль содержит пользовательский Сериализатор , который Джексон будет использовать для POJOS, помеченных @JsonldResource аннотацией .

Затем мы продолжим и используем ObjectMapper для создания документа JSON-LD:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JsonldModule());

Person person = new Person("http://example.com/person/1234", "Example Name");
String personJsonLd = objectMapper.writeValueAsString(person);

В результате человек JsonLd переменная теперь должна содержать:

{
  "@type": "s:Person",
  "@context": {
    "s": "http://schema.org/",
    "name": "s:name",
    "knows": {
      "@id": "s:knows",
      "@type": "@id"
    }
  },
  "name": "Example Name",
  "@id": "http://example.com/person/1234",
  "knows": "http://example.com/person/2345"
}

4.3. Соображения

Прежде чем мы выберем эту библиотеку для проекта, мы должны рассмотреть следующее:

  • Использование ключевого слова @vocab невозможно, поэтому нам придется либо использовать пространство @JsonldNamespace для сокращения имен полей, либо каждый раз выписывать полный интернационализированный идентификатор ресурса (IRI)
  • Мы можем определять ссылки только во время компиляции, поэтому, чтобы добавить среду выполнения ссылок, нам нужно будет использовать отражение для изменения этого параметра в аннотации

5. Сериализация С Помощью Hydra-Json ld

Hydra-Json ld-это модуль библиотеки Hydra-Java , который в первую очередь предназначен для удобного создания ответов JSON-LD для приложений Spring. Он использует словарь Hydra , чтобы сделать документы JSON-LD более выразительными.

Однако , модуль Hydra-Json ld содержит сериализатор Джексона и некоторые аннотации, которые мы можем использовать для создания документов JSON-LD за пределами Spring Framework .

5.1. Зависимости Maven

Во-первых, давайте добавим зависимость для hydra-json ld в pom.xml :


    de.escalon.hypermedia
    hydra-jsonld
    0.4.2

5.2. Пример

Во-вторых, давайте аннотируем наше POJO для @context generation.

Hydra-Json ld автоматически генерирует по умолчанию @context без необходимости в аннотациях. Если нас устраивают значения по умолчанию, нам нужно только добавить @id , чтобы получить действительный документ JSON-LD.

Словарный запас по умолчанию будет schema.org словарь, @type Java class name и общедоступные свойства POJO будут включены в результирующий документ JSON-LD.

В этом примере давайте переопределим эти значения по умолчанию пользовательскими значениями :

@Vocab("http://example.com/vocab/")
@Expose("person")
public class Person {
    private String id;
    private String name;

    // constructor

    @JsonProperty("@id")
    public String getId() {
        return id;
    }

    @Expose("fullName")
    public String getName() {
        return name;
    }
}

Опять же, давайте подробнее рассмотрим связанные с этим шаги:

  • По сравнению с примером Jackson-Json ld, мы исключили поле knows из нашего POJO из-за ограничений Hydra-Jsonld за пределами фреймворка Spring
  • Мы устанавливаем наш предпочтительный словарь с помощью аннотации @Vocab
  • Используя аннотацию @Expose в классе, мы устанавливаем другой тип ресурса @
  • Мы использовали ту же аннотацию @Expose для свойства, чтобы установить его сопоставление с пользовательским значением в контексте @
  • Для создания @id из свойства мы использовали аннотацию @JsonProperty из Джексона

Далее, давайте настроим экземпляр модуля Джексона , который мы можем зарегистрировать в ObjectMapper . Мы добавим сериализатор Jackson Hydra в качестве BeanSerializerModifier , чтобы он мог применяться ко всем POJO, которые сериализуются :

SimpleModule getJacksonHydraSerializerModule() {
    return new SimpleModule() {
        @Override
        public void setupModule(SetupContext context) {
            super.setupModule(context);

            context.addBeanSerializerModifier(new BeanSerializerModifier() {
                @Override
                public JsonSerializer modifySerializer(
                  SerializationConfig config, 
                  BeanDescription beanDesc, 
                  JsonSerializer serializer) {
                    if (serializer instanceof BeanSerializerBase) {
                        return new JacksonHydraSerializer((BeanSerializerBase) serializer);
                    } else {
                        return serializer;
                    }
                }
            });
        }
    };
}

Тогда давайте зарегистрируем Модуль в ObjectMapper и используем его . Мы также должны установить ObjectMapper для включения только не null значений для создания допустимого документа JSON-LD:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(getJacksonHydraSerializerModule());
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

Person person = new Person("http://example.com/person/1234", "Example Name");

String personJsonLd = objectMapper.writeValueAsString(person);

Теперь, человек JsonLd переменная должна содержать:

{
  "@context": {
    "@vocab": "http://example.com/vocab/",
    "name": "fullName"
  },
  "@type": "person",
  "name": "Example Name",
  "@id": "http://example.com/person/1234"
}

5.3. Соображения

Хотя технически возможно использовать Hydra-Jsonld вне рамок Spring, он изначально был разработан для использования с Spring-HATEOAS . В результате нет возможности создавать ссылки с аннотациями, как мы видели в Jackson-Json ld. С другой стороны, они генерируются для некоторых классов, специфичных для Spring, автоматически.

Прежде чем мы выберем эту библиотеку для проекта, мы должны рассмотреть следующее:

  • Использование его с Spring Framework позволит включить дополнительные функции
  • Нет простого способа генерировать ссылки, если мы не используем фреймворк Spring
  • Мы не можем отключить использование @vocab , мы можем только переопределить его

6. Десериализация с помощью Jsonld-Java и Jackson

Jsonld-Java -это Java-реализация спецификации и API JSON-LD 1.0, которая, к сожалению, не является последней версией.

Для реализации версии спецификации 1.1 ознакомьтесь с библиотекой Titanium JSON-LD .

Чтобы десериализовать документ JSON-LD, давайте преобразуем его с помощью функции API JSON-LD, называемой сжатием, в формат, который мы можем сопоставить с POJO ObjectMapper .

6.1. Зависимости Maven

Во-первых, давайте добавим зависимость для jsonld-java :


    com.github.jsonld-java
    jsonld-java
    0.13.0

6.2. Пример

Давайте работать с этим документом JSON-LD в качестве входных данных:

{
  "@context": {
    "@vocab": "http://schema.org/",
    "knows": {
      "@type": "@id"
    }
  },
  "@type": "Person",
  "@id": "http://example.com/person/1234",
  "name": "Example Name",
  "knows": "http://example.com/person/2345"
}

Для простоты предположим, что у нас есть содержимое документа в переменной String с именем input Json Ld .

Во-первых, давайте компактируем его и преобразуем обратно в Строку :

Object jsonObject = JsonUtils.fromString(inputJsonLd);
Object compact = JsonLdProcessor.compact(jsonObject, new HashMap<>(), new JsonLdOptions());
String compactContent = JsonUtils.toString(compact);
  • Мы можем проанализировать и записать объект JSON-LD с помощью методов из JsonUtils, который является частью библиотеки Jsonld-Java
  • При использовании метода compact в качестве второго параметра мы можем использовать пустую Карту . Таким образом, алгоритм сжатия создаст простой объект JSON, в котором ключи будут разрешены в их ирландские формы

То компактный контент переменная должна содержать:

{
  "@id": "http://example.com/person/1234",
  "@type": "http://schema.org/Person",
  "http://schema.org/knows": {
    "@id": "http://example.com/person/2345"
  },
  "http://schema.org/name": "Example Name"
}

Во-вторых, давайте адаптируем наше POJO с аннотациями Джексона, чтобы соответствовать такой структуре документа:

@JsonIgnoreProperties(ignoreUnknown = true)
public class Person {
    @JsonProperty("@id")
    private String id;
    @JsonProperty("http://schema.org/name")
    private String name;
    @JsonProperty("http://schema.org/knows")
    private Link knows;

    // constructors, getters, setters

    public static class Link {
        @JsonProperty("@id")
        private String id;

        // constructors, getters, setters
    }
}

И, наконец, давайте сопоставим JSON-LD с POJO:

ObjectMapper objectMapper = new ObjectMapper();
Person person = objectMapper.readValue(compactContent, Person.class);

7. Заключение

В этой статье мы рассмотрели две библиотеки на основе Джексона для сериализации POJO в документ JSON-LD и один способ десериализации JSON-LD в POJO.

Как мы уже подчеркивали, обе библиотеки сериализации имеют недостатки, которые мы должны рассмотреть перед их использованием. Если нам нужно использовать больше возможностей JSON-LD, чем могут предложить эти библиотеки, мы могли бы подойти к созданию вашего документа с помощью библиотеки RDF с форматом вывода JSON-LD.

Как обычно, исходный код можно найти на GitHub .