JSON kezelés Javában

Kategória: Java külső könyvtárak.

A JSON a JavaScript Object Notation rövidítése, és ahogy a nevéből is kikövetkeztethető, először a JavaScript objektumok szerializálására használták. Kulcs-érték párokból áll, ami az attribútumnak és az értékének felel meg, de gyűjteményeket is tárolhatunk segítségével. A JSON idővel kinőtte magát, mivel jóval általánosabb célokra is használható a JavaScripten túl. Az ember és a gép számára is jól olvasható, könnyen kiterjeszthető, viszonylag tömör. Jelenleg ez a számítógépek közötti adatcsere leggyakoribb formátuma azokan az esetekben is, ahol nincs JavaScript a kommunikációban.

A két legfontosabb művelet az alábbi:
- Objektum → JSON
- JSON → objektum

Ebben a szakaszban ezeket nézzük meg különböző módokon. Mindegyik megvalósítás ennél jóval többet tud, mellyel akkor érdemes megismerkedni, ha szükség van rá. Tipikus probléma egyébként a körkörös hivatkozás: ha az egyik objektum hivatkozik a másikra, és a másik az egyikre, akkor végtelenre nő a JSON mérete. Ezekben az esetekben le kell rögzíteni azt, hogy melyik oldal vezéreli a kapcsolatot.

Jackson

A Jackson az egyik legelterjedtebb JSON kezelő könyvtár, számos nagyobb rendszer használja. A pom.xml-be írjuk be a függőséget:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>hu.faragocsaba</groupId>
    <artifactId>jacksonexample</artifactId>
    <version>1.0</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.10.1</version>
        </dependency>
    </dependencies>
</project>

Hozzuk létre azokat az osztályokat, amelyekből JSOn-t szeretnénk készíteni, ill. amikre szeretnénk betölteni a JSON-t. A példában személyek szerepelnek, akiknek lehetnek lakcímeik. Egy személynek egy lakcíme van, de ugyanazon a lakcímen többen is lakhatnak. Atipikus módon a lakcím fogja kezelni a kapcsolatot és azt fogjuk konvertálni, hogy jól lássuk a gyűjtemények konvertálását is.

src/main/java/data/Person.java:

package data;

import com.fasterxml.jackson.annotation.JsonBackReference;

public class Person {
    private String name;
    private int age;
    @JsonBackReference private Address address;

    public Person() {}

    public Person(String name, int age, Address address) {
        super();
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
}

src/main/java/data/Address.java:

package data;

import java.util.ArrayList;
import java.util.List;

import com.fasterxml.jackson.annotation.JsonManagedReference;

public class Address {
    private String country;
    private String town;
    private String street;
    @JsonManagedReference private List<Person> persons = new ArrayList<Person>();

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getTown() {
        return town;
    }

    public void setTown(String town) {
        this.town = town;
    }

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public List<Person> getPersons() {
        return persons;
    }

    public void setPersons(List<Person> persons) {
        this.persons = persons;
    }

    public void addPerson(Person person) {
        persons.add(person);
    }

    @Override
    public String toString() {
        return "Address [country=" + country + ", town=" + town + ", street=" + street + ", persons=" + persons + "]";
    }
}

A példa, ami átkonvertálja az objektumok JSON-ba ill. fordítva:

src/main/java/logic/JacksonLogic.java:

package logic;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import data.Address;
import data.Person;

public class JacksonLogic {
    public static void objectToJson() {
        Address address = new Address();
        address.setCountry("Hungary");
        address.setTown("Budapest");
        address.setStreet("Pipacs utca 1");
        address.addPerson(new Person("Sanyi", 32, address));
        address.addPerson(new Person("Pista", 40, address));
        address.addPerson(new Person("Gyuri", 42, address));

        try {
            ObjectMapper mapper = new ObjectMapper();
            String objectAsJson = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(address);
            System.out.println(objectAsJson);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

    public static void jsonToObject() {
        String jsonInString = "{\"country\":\"Hungary\",\"town\":\"Budapest\",\"street\":\"Pipacs utca 1\",\"persons\":[{\"name\":\"Sanyi\",\"age\":32},{\"name\":\"Pista\",\"age\":40},{\"name\":\"Gyuri\",\"age\":42}]}";
        try {
            ObjectMapper mapper = new ObjectMapper();
            Address address = mapper.readValue(jsonInString, Address.class);
            System.out.println(address);
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        objectToJson();
        jsonToObject();
    }
}

Ha mindent jól csináltunk, akkor minkét konverzió rendben lefut, és a körkörös hivatkozás is megfelelően van kezelve.

Egyéb keretrendszerek

Noha a Jackson igen nagy népszerűségre tett szert, egyéb keretrendszerek is megjelentek, melyeket legalább felsorolás szintjén érdemes megemlíteni. Mivel a Jackson-nak is csak a felszínét érintettük, ahhoz is adok plusz forrásokat.

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License