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 .