JSON-Bを利用してJSONをPOJOにバインディング

はじめに

JSON-Bを利用してJSONPOJOにバインドするサンプル。 JSON-Bの実装は、参照実装のYassonを利用。

ディレクトリ構成

.
|-- pom.xml
`-- src
    |-- main
    |   `-- java
    |       `-- redj
    |           `-- jsonb
    |               `-- binding
    |                   |-- Person.java
    |                   `-- Root.java
    `-- test
        |-- java
        |   `-- redj
        |       `-- jsonb
        |           `-- JsonbTest.java
        `-- resources
            `-- redj
                `-- jsonb
                    `-- data.json

ソースコード

src/test/resources/redj/jsonb/data.json

テストデータとして、以下のJSONを利用。

{
    "persons": [
        {
            "first-name": "Ichiro",
            "last-name": "Yamada",
            "age": 20
        },
        {
            "first-name": "Taro",
            "last-name": "Suzuki",
            "age": 30
        }
    ]
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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>redj-jsonb</groupId>
    <artifactId>redj-jsonb</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
   
  
    <properties>
        <!-- configurations -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        
        <!-- dependency versions -->
        <junit.version>4.12</junit.version>
        <javax.json.bind-api.version>1.0</javax.json.bind-api.version>
        <yasson.version>1.0</yasson.version>
        <javax.json.version>1.1</javax.json.version>
    </properties>
        
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        
        <dependency>
            <groupId>javax.json.bind</groupId>
            <artifactId>javax.json.bind-api</artifactId>
            <version>${javax.json.bind-api.version}</version>
        </dependency>
                    
        <dependency>
            <groupId>org.eclipse</groupId>
            <artifactId>yasson</artifactId>
            <version>${yasson.version}</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish</groupId>
            <artifactId>javax.json</artifactId>
            <version>${javax.json.version}</version>
        </dependency>    
    </dependencies>
</project>

src/main/java/redj/jsonb/binding/Root.java

テストデータのJSONのルートにあたるクラス。

package redj.jsonb.binding;

import java.util.List;
import javax.json.bind.annotation.JsonbProperty;

public class Root {

    @JsonbProperty(value = "persons")
    public List<Person> persons;
}

src/main/java/redj/jsonb/binding/Person.java

テストデータのJSONの配列personsの各要素にあたるクラス。

package redj.jsonb.binding;

import javax.json.bind.annotation.JsonbProperty;

public class Person {

    @JsonbProperty(value = "first-name")
    public String firstName;

    @JsonbProperty(value = "last-name")
    public String lastName;

    @JsonbProperty(value = "age")
    public int age;
}

src/test/java/redj/jsonb/JsonbTest.java

data.jsonPOJOに変換し、そのPOJOをもう一度JSONに変換して標準出力に出力するテスト。 標準出力に出力する際に、整形したJSONになるようにJsonConfigを設定している。

テストの最後で改行を出力しているのは、単にMavenの出力の見た目を整えるため。

package redj.jsonb;

import java.io.IOException;
import java.io.InputStream;
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
import javax.json.bind.JsonbConfig;
import org.junit.Test;
import redj.jsonb.binding.Root;

public class JsonbTest {

    @Test
    public void test() throws IOException {
        try (InputStream in = getClass().getClassLoader().getResourceAsStream("redj/jsonb/data.json")) {
            // configure JSON-B
            JsonbConfig jsonbConfig = new JsonbConfig()
                    .withFormatting(true);

            // create Jsonb instance
            Jsonb jsonb = JsonbBuilder.create(jsonbConfig);

            // deserialize and serialize 
            Root root = jsonb.fromJson(in, Root.class);
            jsonb.toJson(root, System.out);

            // I want a newline !!
            System.out.println();
        }
    }
}

ビルドとテスト

$ mvn clean test
(略)
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running redj.jsonb.JsonbTest

{
    "persons": [
        {
            "age": 20,
            "first-name": "Ichiro",
            "last-name": "Yamada"
        },
        {
            "age": 30,
            "first-name": "Taro",
            "last-name": "Suzuki"
        }
    ]
}
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.682 sec
(略)

参考