A Jackson egy népszerű könyvtár Java objektumok szerializálására/deszerializálására különféle szövegformátumokba. Az ObjectMapper osztály a könyvtár fő módja a JSON formátummal való munkavégzésnek. Más formátumoknál megvannak a leszármazottai ( XmlMapper , YAMLMapper ). Az öröklődésnek köszönhetően minden formátummal konzisztens módon, egyetlen felületen keresztül tudunk dolgozni.

Jar fájlok letöltése

A példák tanulmányozása előtt le kell töltenünk a Jackson jar fájlokat, és csatlakoztatnunk kell őket a projekthez az IntelliJ IDEA-ban. Vegyük a jackson-databind példáját , hogy megtudjuk, hogyan lehet keresni a szükséges fájlokat:

  1. Nyissa meg a Maven Repository webhelyet.

  2. Írja be a " jackson-databind " kifejezést a keresőmezőbe. A következőket kapod:

  3. Az első keresési eredmény az, ami érdekel minket. Kövesse a linket.

  4. Néha egy könyvtár adott verziójára lehet szükség a projekt más összetevőivel való kompatibilitás biztosításához. A legújabb verziónak működnie kell (a lecke írásakor ez 2.13.2.2). Kövesse a linket.

  5. A megnyíló oldalon a "csomag" linket szeretné látni:

  6. Töltse le a jar fájlt erről a linkről .

Hasonló eljárást követve megtalálhatja és letöltheti a többi szükséges jar fájlt:

Az összes szükséges fájl letöltése után csatlakoztassa őket az IntelliJ IDEA projekthez:

  1. Nyissa meg a projektbeállításokat (a Ctrl+Alt+Shift+S billentyűkombinációval teheti meg ).

  2. Lépjen a Könyvtárak oldalra .

  3. Nyomja meg a + , majd a „Java” gombot. Válassza ki az összes letöltött fájlt. Íme, mire kell végződnünk:

  4. Ezzel az előkészítő munkánk véget ért. Most kipróbálhatjuk az ObjectMappert működés közben.

Sorozatosítás JSON-ba

Először sorosítsunk néhány objektumot JSON-ba:


import com.fasterxml.jackson.databind.ObjectMapper;
 
class Book {
	public String title;
	public String author;
	public int pages;
}
 
public class Solution {
	public static void main(String[] args) throws Exception {
    	Book book = new Book();
    	book.title = "Good Omens";
    	book.author = "Pratchett T., Gaiman N.";
    	book.pages = 383;
 
    	ObjectMapper mapper = new ObjectMapper();
    	String jsonBook = mapper.writeValueAsString(book);
    	System.out.println(jsonBook);
	}
}

A fő futtatása ezt a kimenetet adja:

{"title":"Jó előjelek","author":"Pratchett T., Gaiman N.","oldalak":383}

Az ObjectMapper számos speciális beállítással rendelkezik. Használjuk az egyiket, hogy olvashatóbbá tegyük a JSON-karakterláncot. Miután létrehozta aObjectMapperobjektum, hajtsa végre ezt az utasítást:

mapper.enable(SerializationFeature.INDENT_OUTPUT);

A kimenetben lévő információ változatlan marad, de most behúzások és sortörések vannak:

{
  "title" : "Jó előjelek",
  "szerző" : "Pratchett T., Gaiman N.",
 "oldalak" : 383
}

Deszerializálás JSON-ból

Most végezzük el az ellenkező műveletet: egy karakterláncot objektummá deszerializálunk. Ahhoz, hogy lássuk, mit csinál a program, írjuk felül a toString metódust a Book osztályban:


@Override
public String toString() {
	return "Book{" +
        	"title='" + title + '\'' +
        	", author='" + author + '\'' +
        	", pages=" + pages +
        	'}';
}

És a fő módszerben a következőket tesszük :


public static void main(String[] args) throws Exception {
	String jsonString = "{\"title\":\"Good Omens\",\"author\":\"Pratchett T., Gaiman N.\",\"pages\":383}";
	Book book = new ObjectMapper().readValue(jsonString, Book.class);
	System.out.println(book);
}

Kimenet:

Book{title='Jó előjelek', author='Pratchett T., Gaiman N.', pages=383}

A readValue metódus túlterhelt – számos változata van, amelyek egy fájlt, egy hivatkozást, különféle bemeneti adatfolyamokat stb. foglalnak magukba. Az egyszerűség kedvéért példánk olyan változatot használ, amely elfogad egy JSON-karakterláncot.

Mint fentebb említettük, az ObjectMapper számos beállítással rendelkezik. Nézzünk meg ezek közül néhányat.

Ismeretlen tulajdonságok figyelmen kívül hagyása

Vegyünk egy olyan helyzetet, amikor egy JSON-karakterlánc olyan tulajdonsággal rendelkezik, amely nem létezik a Book osztályban:


public static void main(String[] args) throws Exception {
	String jsonString = """
        	{
          	"title" : "Good Omens",
          	"author" : "Pratchett T., Gaiman N.",
          	"pages" : 383,
          	"unknown property" : 42
        	}""";
	ObjectMapper mapper = new ObjectMapper();
	Book book = mapper.readValue(jsonString, Book.class);
	System.out.println(book);
}

Ennek a kódnak a végrehajtása UnrecognizedPropertyExceptiont ad nekünk . Ez az alapértelmezett viselkedés, de megváltoztathatjuk:


ObjectMapper mapper =
new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

Amikor létrehoz egyObjectMapperobjektum esetén a configurációs módszerrel állítjuk be a megfelelő beállítást false értékre . A configure metódus módosítja a meghívott objektumot, majd ugyanazt az objektumot adja vissza, így ezt a hívást más módon hajthatjuk végre:


ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

Funkcionalitás szempontjából ez a jelölés az előzőhöz hasonló.

Ha most lefuttatjuk a metódust, a deserializálás sikeres lesz, és az ismeretlen tulajdonság figyelmen kívül lesz hagyva.

Kényelmes megjegyzések

Jackson számos megjegyzést biztosít számunkra, amelyek lehetővé teszik számunkra, hogy mindenféle módon testreszabhassuk a sorozatkészítési folyamatot. Nézzünk néhányat a leghasznosabbak közül:

@JsonIgnore — Ez a megjegyzés egy olyan elem fölé kerül, amelyet figyelmen kívül kell hagyni a szerializálás/deszerializálás során:


class Book {
	public String title;
	@JsonIgnore
	public String author;
	public int pages;
}

Itt aszerzőmező nem fog szerepelni az eredményül kapott JSON-ban a szerializálás során. A deserializáláskor aszerzőmező az alapértelmezett értéket (null) kapja, még akkor is, ha a JSON eltérő értéket kapott.

@JsonFormat — Ez a megjegyzés lehetővé teszi a sorosított adatok formátumának beállítását. Adjunk hozzá még egy mezőt, egy dátumot a Könyv osztályhoz:


class Book {
	public String title;
	public String author;
	public int pages;
	public Date createdDate = new Date();
}

A szerializálás után a következő JSON-t kapjuk:

 {
  "title" : "Jó előjelek",
  "szerző" : "Pratchett T., Gaiman N.",
  "pages" : 383,
  "createdDate" : 1649330880788
}

Amint láthatja, a dátumot számként adták meg. Hozzáadunk egy megjegyzést, és beállítjuk a formátumot:


class Book {
	public String title;
	public String author;
	public int pages;
	@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
	public Date createdDate = new Date();
}

Most a sorozatosítás eredménye:

{
  "title" : "Jó előjelek",
  "author" : "Pratchett T., Gaiman N.",
  "pages" : 383,
  "createdDate" : "2022-04-07"
}

@JsonProperty — Ez a megjegyzés lehetővé teszi a sorosított mezőt képviselő tulajdonság nevének módosítását. Ezzel a megjegyzéssel metódusokat is megjelölhet. Ha megteszi, akkor a visszatérési értékük a szerializálás során JSON-tulajdonsággá alakul:


class Book {
	@JsonProperty("name")
	public String title;
	public String author;
	public int pages;
 
	@JsonProperty("quotedTitle")
	public String getQuotedTitle() {
    	    return "\"" + title + "\"";
	}
}

A szeralizálás eredménye:

{
  "author" : "Pratchett T., Gaiman N.",
  "oldalak" : 383,
  "name" : "Jó előjelek",
  "quotedTitle" : "\"Jó előjelek\""
}

@JsonInclude — Ezzel az annotációval megadhatja azokat a feltételeket, amelyeknek teljesülniük kell egy mező sorosításához. Alkalmazhatja egyes mezőkre vagy egy egész osztályra. Először próbáljunk meg szerializálni egy objektumot inicializálatlan mezőkkel:


public class Solution {
	public static void main(String[] args) throws Exception {
    		Book book = new Book();

    		ObjectMapper mapper = new ObjectMapper();
    		mapper.enable(SerializationFeature.INDENT_OUTPUT);
    		String jsonBook = mapper.writeValueAsString(book);
    		System.out.println(jsonBook);
	}
}

A szeralizálás eredménye:

{
  "cím" : null,
  "szerző" : null,
  "oldalak" : 0
}

És ha hozzáadja a megjegyzést:


@JsonInclude(JsonInclude.Include.NON_NULL)
class Book {
	public String title;
	public String author;
	public int pages;
}

Akkor ezt az eredményt kapjuk:

{
  "oldalak" : 0
}

A null mezők most nincsenek sorosítva.

@JsonPropertyOrder — Ezzel a megjegyzéssel beállíthatja a mezők sorba rendezésének sorrendjét:


@JsonPropertyOrder({"author", "title", "pages"})
class Book {
	public String title;
	public String author;
	public int pages;
}

A szeralizálás eredménye:

{
  "author" : "Pratchett T., Gaiman N.",
  "title" : "Jó előjelek",
  "oldalak" : 383
}

Egyelőre csak emlékezzen a kommentárok használatára. A modul végén jobban megismerjük őket, sőt saját megjegyzéseket is készítünk.

Sorozatosítás és deszerializálás XML-ben

Ha XML-be kell szerializálnunk, akkor ugyanazokat a beállításokat és megjegyzéseket használhatjuk. Az egyetlen különbség a végrehajtása lesztérképező objektum:


public static void main(String[] args) throws Exception {
	Book book = new Book();
	book.title = "Good Omens";
	book.author = "Pratchett T., Gaiman N.";
	book.pages = 383;
 
	ObjectMapper mapper = new XmlMapper();
	mapper.enable(SerializationFeature.INDENT_OUTPUT);
	String xmlBook = mapper.writeValueAsString(book);
	System.out.println(xmlBook);
}

Kimenet:

 <Book>
  <title>Jó előjelek</title>
  <author>Pratchett T., Gaiman N.</author>
  <pages>383</pages>
</Book>

XML deszerializálása:


public static void main(String[] args) throws Exception {
   String xmlString = """
            <Book>
             <title>Good Omens</title>
             <author>Pratchett T., Gaiman N.</author>
             <pages>383</pages>
           </Book>""";
   ObjectMapper mapper = new XmlMapper();
   Book book = mapper.readValue(xmlString, Book.class);
   System.out.println(book);
}

Sorozatosítás és deszerializálás a YAML-ben

A YAML-t ugyanúgy kezeljük, mint az XML-t:


public static void main(String[] args) throws Exception {
	Book book = new Book();
	book.title = "Good Omens";
	book.author = "Pratchett T., Gaiman N.";
	book.pages = 383;
 
	ObjectMapper mapper = new YAMLMapper();
	mapper.enable(SerializationFeature.INDENT_OUTPUT);
	String yamlBook = mapper.writeValueAsString(book);
	System.out.println(yamlBook);
}

Kimenet:

---
cím: "Jó előjelek"
szerző: "Pratchett T., Gaiman N."
oldal: 383

A YAML deszerializálása:


public static void main(String[] args) throws Exception {
   String yamlString = """
           ---
           title: "Good Omens"
           author: "Pratchett T., Gaiman N."
           pages: 383""";
   ObjectMapper mapper = new YAMLMapper();
   Book book = mapper.readValue(yamlString, Book.class);
   System.out.println(book);
}