Hypermedia-serialisering met JSON-LD

1. Overzicht

JSON-LD is een op JSON gebaseerd RDF-formaat voor het weergeven van gekoppelde gegevens. Het maakt het mogelijk om bestaande JSON-objecten uit te breiden met hypermedia-mogelijkheden; met andere woorden, de mogelijkheid om links op een machineleesbare manier te bevatten.

In deze tutorial we zullen een aantal Jackson-gebaseerde opties bekijken om het JSON-LD-formaat rechtstreeks in POJO's te serialiseren en deserialiseren. We behandelen ook de basisconcepten van JSON-LD waarmee we de voorbeelden kunnen begrijpen.

2. Basisconcepten

De eerste keer dat we een JSON-LD-document zien, merken we dat sommige ledennamen beginnen met de @ karakter. Dit zijn JSON-LD-sleutelwoorden en hun waarden helpen ons de rest van het document te begrijpen.

Om door de wereld van JSON-LD te navigeren en deze tutorial te begrijpen, moeten we op de hoogte zijn van vier sleutelwoorden:

  • @context is de beschrijving van het JSON-object dat een sleutelwaarde-kaart bevat van alles wat nodig is voor de interpretatie van het document
  • @vocab is een mogelijke sleutel in @context dat een standaardwoordenschat introduceert om de @context object veel korter
  • @ID kaart is het sleutelwoord om links te identificeren als een resource-eigenschap om de directe link naar de resource zelf weer te geven of als een @type waarde om een ​​veld als een link te markeren
  • @type is het sleutelwoord om resourcetypen te identificeren op resourceniveau of in de @context; bijvoorbeeld om het type ingebedde bronnen te definiëren

3. Serialisatie in Java

Voordat we verder gaan, moeten we onze vorige tutorials bekijken om ons geheugen op de Jackson op te frissen ObjectMapper, Jackson Annotations en aangepaste Jackson Serializers.

Omdat we al bekend zijn met Jackson, realiseren we ons misschien dat we gemakkelijk twee aangepaste velden in elke POJO kunnen serialiseren als @ID kaart en @type de ... gebruiken @JsonProperty annotatie. Echter, het schrijven van de @context met de hand kan veel werk zijn en ook foutgevoelig.

Laten we daarom, om deze foutgevoelige benadering te vermijden, twee bibliotheken nader bekijken die we voor zouden kunnen gebruiken @context generatie. Helaas is geen van beiden in staat om alle functies van JSON-LD te genereren, maar we zullen later ook hun tekortkomingen bekijken.

4. Serialisatie met Jackson-Jsonld

Jackson-Jsonld is een Jackson-module waarmee op een gemakkelijke manier POJO's kunnen worden geannoteerd om JSON-LD-documenten te genereren.

4.1. Afhankelijkheden van Maven

Laten we eerst toevoegen jackson-jsonld als afhankelijkheid van de pom.xml:

 com.io-informatics.oss jackson-jsonld 0.1.1 

4.2. Voorbeeld

Laten we vervolgens ons voorbeeld-POJO maken en er aantekeningen voor maken @context generatie:

@JsonldResource @JsonldNamespace (name = "s", uri = "//schema.org/") @JsonldType ("s: Person") @JsonldLink (rel = "s: weet", naam = "weet", href = "//example.com/person/2345") openbare klasse Persoon {@JsonldId privé String-id; @JsonldProperty ("s: name") private String naam; // constructor, getters, setters}

Laten we de stappen deconstrueren om te begrijpen wat we hebben gedaan:

  • Met @JsonldResource we hebben de POJO gemarkeerd voor verwerking als een JSON-LD-bron
  • In de @JsonldNamespace we hebben een afkorting gedefinieerd voor de woordenschat die we willen gebruiken
  • De parameter die we hebben gespecificeerd in @JsonldType wordt de @type van de bron
  • We gebruikten de @JsonldLink annotatie om links naar de bron toe te voegen. Bij verwerking wordt het naam parameter wordt gebruikt als een veldnaam en wordt ook toegevoegd als een sleutel voor de @context.href zal de veldwaarde zijn en rel is de toegewezen waarde in de @context
  • Het veld waarmee we hebben gemarkeerd @RTLnieuws wordt de @ID kaart van de bron
  • De parameter die we hebben gespecificeerd in @JsonldProperty wordt de waarde die is toegewezen aan de naam van het veld in de @context

Laten we vervolgens het JSON-LD-document genereren.

Ten eerste moeten we het JsonldModule in de ObjectMapper. Deze module bevat een custom Serializer die Jackson zal gebruiken voor POJO's die zijn gemarkeerd met de @JsonldResource annotatie.

Daarna gaan we verder en gebruiken we de ObjectMapper om het JSON-LD-document te genereren:

ObjectMapper objectMapper = nieuwe ObjectMapper (); objectMapper.registerModule (nieuwe JsonldModule ()); Persoon person = nieuwe persoon ("// voorbeeld.com/persoon/1234", "Voorbeeldnaam"); String personJsonLd = objectMapper.writeValueAsString (persoon);

Als gevolg hiervan is het personJsonLd variabele zou nu moeten bevatten:

{"@type": "s: Person", "@context": {"s": "//schema.org/", "name": "s: name", "weet": {"@id" : "s: weet", "@type": "@id"}}, "naam": "Voorbeeldnaam", "@id": "//voorbeeld.com/persoon/1234", "weet": " //voorbeeld.com/persoon/2345 "}

4.3. Overwegingen

Voordat we deze bibliotheek voor een project kiezen, moeten we het volgende overwegen:

  • De ... gebruiken @vocab trefwoord is niet mogelijk, dus we zullen ofwel de @JsonldNamespace om een ​​afkorting te geven voor het oplossen van veldnamen of om elke keer de volledige Internationalized Resource Identifier (IRI) uit te schrijven
  • We kunnen alleen links definiëren tijdens het compileren, dus om een ​​linkruntime toe te voegen, zouden we reflectie moeten gebruiken om die parameter in de annotatie te wijzigen

5. Serialisatie met Hydra-Jsonld

Hydra-Jsonld is een module van de Hydra-Java-bibliotheek, die voornamelijk is gebouwd om gemakkelijk JSON-LD-responscreatie voor Spring-toepassingen mogelijk te maken. Het gebruikt de Hydra-woordenschat om de JSON-LD-documenten expressiever te maken.

Echter, de Hydra-Jsonld-module bevat een Jackson Serializer en enkele annotaties die we kunnen gebruiken om JSON-LD-documenten buiten het Spring Framework te genereren.

5.1. Afhankelijkheden van Maven

Laten we eerst de afhankelijkheid toevoegen voor hydra-jsonld naar de pom.xml:

 de.escalon.hypermedia hydra-jsonld 0.4.2 

5.2. Voorbeeld

Ten tweede, laten we onze POJO annoteren voor @context generatie.

Hydra-Jsonld genereert automatisch een standaard @context zonder de noodzaak van annotaties. Als we tevreden zijn met de standaardinstellingen, hoeven we alleen de @ID kaart om een ​​geldig JSON-LD-document te krijgen.

Het standaardwoordenschat is het schema.org-vocabulaire, het @type de Java klasse name, en de openbare eigenschappen van de POJO zullen allemaal worden opgenomen in het resulterende JSON-LD-document.

In dit voorbeeld laten we deze standaardinstellingen overschrijven met aangepaste waarden:

@Vocab ("// example.com/vocab/") @Expose ("persoon") openbare klasse Persoon {privé String-id; private String naam; // constructor @JsonProperty ("@ id") public String getId () {return id; } @Expose ("fullName") public String getName () {return naam; }}

Nogmaals, laten we de stappen van naderbij bekijken:

  • In vergelijking met het voorbeeld van Jackson-Jsonld hebben we de weet veld van onze POJO vanwege de beperkingen van Hydra-Jsonld buiten het Spring Framework
  • We hebben onze favoriete woordenschat ingesteld met de @Vocab annotatie
  • Door de @Expose annotatie op de klasse, stellen we een andere bron in @type
  • We gebruikten hetzelfde @Expose annotatie op een eigenschap om de toewijzing ervan in te stellen op een aangepaste waarde in de @context
  • Voor het genereren van de @ID kaart van een woning, gebruikten we de @JsonProperty annotatie van Jackson

Laten we vervolgens een instantie van een Jackson configureren Module die we kunnen registreren in het ObjectMapper. We voegen de JacksonHydraSerializer als een BeanSerializerModifier dus het kan worden toegepast op alle POJO's die worden geserialiseerd:

SimpleModule getJacksonHydraSerializerModule () {retourneer nieuwe SimpleModule () {@Override public void setupModule (SetupContext-context) {super.setupModule (context); context.addBeanSerializerModifier (nieuwe BeanSerializerModifier () {@Override openbare JsonSerializer modificerenSerializer (SerializationConfig config, BeanDescription beanDesc, JsonSerializer serializer) {if (serializer-instantie van BeanSerializerBase) {return nieuwe serializer () }); }}; }

Laten we dan het Module in ObjectMapper en gebruik het. We moeten ook de ObjectMapper om alleen niet-nul waarden om een ​​geldig JSON-LD-document te produceren:

ObjectMapper objectMapper = nieuwe ObjectMapper (); objectMapper.registerModule (getJacksonHydraSerializerModule ()); objectMapper.setSerializationInclusion (JsonInclude.Include.NON_NULL); Persoon person = nieuwe persoon ("// voorbeeld.com/persoon/1234", "Voorbeeldnaam"); String personJsonLd = objectMapper.writeValueAsString (persoon);

Nu de personJsonLd variabele moet bevatten:

{"@context": {"@vocab": "//example.com/vocab/", "name": "fullName"}, "@type": "person", "name": "Voorbeeldnaam", "@id": "//voorbeeld.com/persoon/1234"}

5.3. Overwegingen

Hoewel het technisch mogelijk is om Hydra-Jsonld buiten het Spring Framework te gebruiken, was het oorspronkelijk ontworpen voor gebruik met Spring-HATEOAS. Als gevolg hiervan is er geen manier om links met annotaties te genereren, zoals we hebben gezien in Jackson-Jsonld. Aan de andere kant worden ze automatisch gegenereerd voor sommige Spring-specifieke klassen.

Voordat we deze bibliotheek voor een project kiezen, moeten we het volgende overwegen:

  • Als u het gebruikt met het Spring Framework, worden extra functies ingeschakeld
  • Er is geen gemakkelijke manier om links te genereren als we het Spring Framework niet gebruiken
  • We kunnen het gebruik van @vocab, we kunnen het alleen negeren

6. Deserialisatie met Jsonld-Java en Jackson

Jsonld-Java is de Java-implementatie van de JSON-LD 1.0-specificatie en API, die helaas niet de laatste versie is.

Bekijk de Titanium JSON-LD-bibliotheek voor een implementatie van de 1.1-specificatieversie.

Om een ​​JSON-LD-document te deserialiseren, laten we het transformeren met een JSON-LD API-functie, compaction genaamd, naar een formaat dat we kunnen toewijzen aan een POJO met ObjectMapper.

6.1. Afhankelijkheden van Maven

Laten we eerst de afhankelijkheid toevoegen voor jsonld-java:

 com.github.jsonld-java jsonld-java 0.13.0 

6.2. Voorbeeld

Laten we werken met dit JSON-LD-document als onze invoer:

{"@context": {"@vocab": "//schema.org/", "know": {"@type": "@id"}}, "@type": "Person", "@id ":" //voorbeeld.com/persoon/1234 "," naam ":" Voorbeeldnaam "," weet ":" //voorbeeld.com/persoon/2345 "}

Laten we voor de eenvoud aannemen dat we de inhoud van het document in een Draad variabele genaamd inputJsonLd.

Laten we het eerst comprimeren en terug converteren naar een Draad:

Object jsonObject = JsonUtils.fromString (inputJsonLd); Object compact = JsonLdProcessor.compact (jsonObject, nieuwe HashMap (), nieuwe JsonLdOptions ()); String compactContent = JsonUtils.toString (compact);
  • We kunnen het JSON-LD-object parseren en schrijven met methoden uit de JsonUtils, dat deel uitmaakt van de Jsonld-Java-bibliotheek
  • Bij gebruik van de compact methode, als tweede parameter kunnen we een lege Kaart. Op deze manier produceert het verdichtingsalgoritme een eenvoudig JSON-object waarbij de sleutels worden omgezet in hun IRI-formulieren

De compactInhoud variabele moet bevatten:

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

Ten tweede, laten we onze POJO met Jackson-annotaties aanpassen aan een dergelijke documentstructuur:

@JsonIgnoreProperties (ignoreUnknown = true) openbare klasse Persoon {@JsonProperty ("@ id") privé String-id; @JsonProperty ("// schema.org/name") private String naam; @JsonProperty ("// schema.org/knows") private Link weet; // constructeurs, getters, setters openbare statische klasse Link {@JsonProperty ("@ id") privé String-id; // constructeurs, getters, setters}}

En tot slot, laten we de JSON-LD toewijzen aan de POJO:

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

7. Conclusie

In dit artikel hebben we gekeken naar twee op Jackson gebaseerde bibliotheken voor het serialiseren van een POJO in een JSON-LD-document en een manier om een ​​JSON-LD te deserialiseren naar een POJO.

Zoals we hebben benadrukt, hebben beide serialisatiebibliotheken tekortkomingen waarmee we rekening moeten houden voordat we ze gebruiken. Als we meer functies van JSON-LD moeten gebruiken dan deze bibliotheken kunnen bieden, kunnen we het maken van ons document benaderen via een RDF-bibliotheek met JSON-LD-uitvoerformaat.

Zoals gewoonlijk is de broncode te vinden op GitHub.