94
108

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Java】JSONをJavaに、JavaをJSONにする ~GSONとJacksonの使用方法~

Last updated at Posted at 2019-04-21

概要

JavaでWeb APIを利用するときに良く使う JSON→Java、Java→JSON のやり方についてまとめます
また、JSONをHTTP POSTしたりHTTP GETしたりする方法は次の記事でまとめます。

  • 【本稿】JavaでJSONを扱う方法についてまとめます

    • JSONをJavaに変換(デシリアライズ)、JavaをJSONに変換(シリアライズ)するやり方は2通り説明します
      • ライブラリにGSONを使うやり方
      • ライブラリにJacksonを使うやり方
  • 【次稿】JavaでHTTP通信でJSONをPOSTしたり、GETしたりする方法についてもまとめます

    • JavaでHTTP通信をするやり方も2通り説明します
      • OkHttp3を使ったやり方
      • Java標準パッケージであるHttpUrlConnectionを使ったやり方

最短コース ~JSONありきで考える~

外部APIをたたく時など、パースしたいJSON文字列が既に存在していた場合の最短コースで考える。
モデルクラスの自動生成サイトを活用するので、JSONの文字列があればOK(JSON schemaがあれば尚よい)。

サンプルのJSON文字列:example.json
{
    "person": {
        "firstName": "John",
        "lastName": "Doe",
        "address": "NewYork",
        "pets": [
            {"type": "Dog", "name": "Jolly"},
            {"type": "Cat", "name": "Grizabella"},
            {"type": "Fish", "name": "Nimo"}
        ]
    }
}

GSONとJackson

JavaでJSON操作というとGSONJacksonの2つのライブラリを良く使う。
どちらが良いと一概に言えないので両方説明する。

GSON
Google製のライブラリ
image.png

Jackson
パフォーマンスを重視したライブラリ
image.png

GSON編

GSONをつかってJSONをJavaにマッピングする

まずGSONから見ていく。JSONありき、つまり生のJSON文字列からJavaのパーサーを作ろうっていう場合はjsonschema2pojoを使うとお手軽なのでやってみる。

本章のソースコードはこちら
https://github.com/riversun/java-json-gson-jackson-http/tree/master/src/main/java/com/example/gson

GSONのライブラリ依存関係

GSONのライブラリ指定方法は以下のとおり

■ GSONの最新ライブラリ(mavenリポジトリ)
https://mvnrepository.com/artifact/com.google.code.gson/gson

■ GSONのmaven設定例

pom.xml
<dependency>
	<groupId>com.google.code.gson</groupId>
	<artifactId>gson</artifactId>
	<version>2.8.5</version>
</dependency>

■ GSONのgradle設定例

build.gradle
compile 'com.google.code.gson:gson:2.8.5'

(1) jsonschema2pojoを使ってモデルクラス(POJO)を自動生成する

以下のサイトにいって、ペタッと上のJSONを貼る
http://www.jsonschema2pojo.org/

※外部サイトに抵抗がある場合は、ライブラリを使って自前でやることも可能

image.png

■ サイト上で以下のように設定して、Zipを押すとモデルクラスが自動生成される

Package:com.example.gson (パッケージ名、何でも良いが、そのパッケージ名付でソースが自動生成される)
ClassN name:Model (Pojoの最上位のクラス名)
Target language:Java
Source type:JSON(JSON文字列そのものからモデルクラスを推定する)
Annotation style:Gson(パーサーにGSONを使う)
Allow additional properties(JSONに未知のものが混ざっていてもOK)

Zipファイルが生成されるので、ダウンロードして開くと、以下のように3つのjavaファイルが自動生成されている。

(2) 自動生成されたモデルクラス(POJO)を確認

Model.java・・・一番上位となるクラス

Model.java
package com.example.gson;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Model {
    @SerializedName("person")
    @Expose
    public Person person;
}

Person.java・・・"pets":[]のように配列指定されたものはListになる

Person.java
package com.example.gson;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Person {
    @SerializedName("firstName")
    @Expose
    public String firstName;
    @SerializedName("lastName")
    @Expose
    public String lastName;
    @SerializedName("address")
    @Expose
    public String address;
    @SerializedName("pets")
    @Expose
    public List<Pet> pets = null;
}

Pet.java

Pet.java
package com.example.gson;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Pet {
    @SerializedName("type")
    @Expose
    public String type;
    @SerializedName("name")
    @Expose
    public String name;
}

(3) GSONを使って、JSON→Javaの変換

JSONからJavaへの変換、つまりGSONを使ってJSON文字列をJavaのモデルクラスに読み込む
ポイントとなるコードは以下のようになる

Gson gson = new Gson();
Model model = gson.fromJson(json, Model.class);

コード全体は以下のようになる

GsonJson2Java.java

GsonJson2.java
package com.example.gson;

import com.google.gson.Gson;

public class GsonJson2Java {
    public static void main(String[] args) {
        String json = 
                "{" +
                "    \"person\": {" +
                "        \"firstName\": \"John\"," +
                "        \"lastName\": \"Doe\"," +
                "        \"address\": \"NewYork\"," +
                "        \"pets\": [" +
                "            {\"type\": \"Dog\", \"name\": \"Jolly\"}," +
                "            {\"type\": \"Cat\", \"name\": \"Grizabella\"}," +
                "            {\"type\": \"Fish\", \"name\": \"Nimo\"}" +
                "        ]" +
                "    }" +
                "}";

        Gson gson = new Gson();
        Model model = gson.fromJson(json, Model.class);

        System.out.println("firstName:" + model.person.firstName);
        System.out.println("lastName:" + model.person.lastName);
        System.out.println("address:" + model.person.address);
        System.out.println("1st pet:" + model.person.pets.get(0).name);
    }
}

実行結果
firstName:John
lastName:Doe
address:NewYork
1st pet:Jolly

(4) GSONを使って、Java→JSONの変換

さて、今度は JavaからJSONをやる。Javaのモデルクラス(POJO)をJSON化する。

Gson gson = new Gson();
String json = gson.toJson(model);

GsonJava2Json.java

GsonJava2Json.java
package com.example.gson;

import java.util.ArrayList;
import com.google.gson.Gson;

public class GsonJava2Json {
    public static void main(String[] args) {

        Model model = new Model();
        model.person = new Person();
        model.person.firstName = "ジョン";
        model.person.lastName = "ドゥ";
        model.person.address = "ニューヨーク";

        model.person.pets = new ArrayList<Pet>();

        Pet pet1 = new Pet();
        pet1.type = "犬";
        pet1.name = "ジョリー";
        model.person.pets.add(pet1);

        Pet pet2 = new Pet();
        pet2.type = "猫";
        pet2.name = "グリザベラ";
        model.person.pets.add(pet2);

        Pet pet3 = new Pet();
        pet3.type = "魚";
        pet3.name = "ニモ";
        model.person.pets.add(pet3);

        Gson gson = new Gson();
        String json = gson.toJson(model);

        System.out.println(json);
    }
}

これを実行すると以下の通りモデルクラスからJSONを出力できた

実行結果
{"person":{"firstName":"ジョン","lastName":"ドゥ","address":"ニューヨーク","pets":[{"type":"犬","name":"ジョリー"},{"type":"猫","name":"グリザベラ"},{"type":"魚","name":"ニモ"}]}}

(5) GSONを使って、JSONを整形(Pretty Printing)して出力

このようにすると、JSONがインデントされキレイにフォーマットされて出てくる

Gson gson2 = new GsonBuilder().setPrettyPrinting().create();
String prettyJson = gson2.toJson(model);
System.out.println(prettyJson);

実行結果

{
  "person": {
    "firstName": "ジョン",
    "lastName": "ドゥ",
    "address": "ニューヨーク",
    "pets": [
      {
        "type": "犬",
        "name": "ジョリー"
      },
      {
        "type": "猫",
        "name": "グリザベラ"
      },
      {
        "type": "魚",
        "name": "ニモ"
      }
    ]
  }
}

Jackson編

Jacksonは1.x系と2.x系があるが、2.x系を使う

JacksonをつかってJSONをJavaにマッピングする

本章のソースコードはこちら
https://github.com/riversun/java-json-gson-jackson-http/tree/master/src/main/java/com/example/jackson

Jacksonのライブラリ依存関係

Jacksonのライブラリ指定方法は以下のとおり

■ Jacksonの最新ライブラリ(mavenリポジトリ)
https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind

■ Jacksonのmaven設定例

pom.xml
<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-databind</artifactId>
	<version>2.9.8</version>
</dependency>

■ Jacksonのgradle設定例

build.gradle
compile 'com.fasterxml.jackson.core:jackson-databind:2.9.8'

(1) jsonschema2pojoを使ってモデルクラス(POJO)を自動生成する

以下のサイトにいって、ペタッと上のJSONを貼る
http://www.jsonschema2pojo.org/

image.png

■ サイト上で以下のように設定して、Zipを押すとモデルクラスが自動生成される

Package:com.example.jackson (パッケージ名、何でも良いが、そのパッケージ名付でソースが自動生成される)
ClassN name:Model (Pojoの最上位のクラス名)
Target language:Java
Source type:JSON(JSON文字列そのものからモデルクラスを推定する)
Annotation style:jackson 2.x(パーサーにJackson 2.xを使う)
Allow additional properties(JSONに未知のものが混ざっていてもOK)

Zipファイルが生成されるので、ダウンロードして開くと、以下のように3つのjavaファイルが自動生成されている。

(2) 自動生成されたモデルクラス(POJO)を確認

Model .java・・・一番上位となるクラス。追加プロパティを受け入れるために、@JsonAnyGetterをセットしている点が特徴的。また、その為に、GSONよりも冗長になる。

Model.java
package com.example.jackson;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
    "person"
})
public class Model {
    @JsonProperty("person")
    public Person person;
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();
    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }
    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }
}

Person.java・・・@JsonPropertyOrderで出現順序を拘束できる。"pets":[]のように配列指定されたものはListになる。

Person.java
package com.example.jackson;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
    "firstName",
    "lastName",
    "address",
    "pets"
})
public class Person {
    @JsonProperty("firstName")
    public String firstName;
    @JsonProperty("lastName")
    public String lastName;
    @JsonProperty("address")
    public String address;
    @JsonProperty("pets")
    public List<Pet> pets = null;
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();
    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }
    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }
}

Pet.java

Pet.java
package com.example.jackson;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
    "type",
    "name"
})
public class Pet {
    @JsonProperty("type")
    public String type;
    @JsonProperty("name")
    public String name;
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();
    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }
    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }
}

(3) Jacksonを使って、JSON→Javaの変換

JSONからJavaへの変換、つまりJacksonを使ってJSON文字列をJavaのモデルクラスに読み込む
ポイントとなるコードは以下のようになる

ObjectMapper mapper = new ObjectMapper();
Model model = mapper.readValue(json, Model.class);

コード全体は以下のようになる

JacksonJson2Java.java

JacksonJson2Java.java
package com.example.jackson;

import java.io.IOException;

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

public class JacksonJson2Java {
    public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
        String json = "{" +
                "    \"person\": {" +
                "        \"firstName\": \"John\"," +
                "        \"lastName\": \"Doe\"," +
                "        \"address\": \"NewYork\"," +
                "        \"pets\": [" +
                "            {\"type\": \"Dog\", \"name\": \"Jolly\"}," +
                "            {\"type\": \"Cat\", \"name\": \"Grizabella\"}," +
                "            {\"type\": \"Fish\", \"name\": \"Nimo\"}" +
                "        ]" +
                "    }" +
                "}";

        ObjectMapper mapper = new ObjectMapper();
        Model model = mapper.readValue(json, Model.class);

        System.out.println("firstName:" + model.person.firstName);
        System.out.println("lastName:" + model.person.lastName);
        System.out.println("address:" + model.person.address);
        System.out.println("1st pet:" + model.person.pets.get(0).name);
    }
}

(4) Jacksonを使って、Java→JSONの変換

さて、今度は JavaからJSONをやる。Javaのモデルクラス(POJO)をJSON化する。

ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(model);

JacksonJava2Json.java

JacksonJava2Json.java
package com.example.jackson;
import java.util.ArrayList;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonJava2Json {
    public static void main(String[] args) throws JsonProcessingException {

        Model model = new Model();
        model.person = new Person();
        model.person.firstName = "ジョン";
        model.person.lastName = "ドゥ";
        model.person.address = "ニューヨーク";
        model.person.pets = new ArrayList<Pet>();
        Pet pet1 = new Pet();
        pet1.type = "犬";
        pet1.name = "ジョリー";
        model.person.pets.add(pet1);
        Pet pet2 = new Pet();
        pet2.type = "猫";
        pet2.name = "グリザベラ";
        model.person.pets.add(pet2);
        Pet pet3 = new Pet();
        pet3.type = "魚";
        pet3.name = "ニモ";
        model.person.pets.add(pet3);

        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(model);
        System.out.println(json);
    }
}

これを実行すると以下の通りモデルクラスからJSONを出力できた

実行結果
{"person":{"firstName":"ジョン","lastName":"ドゥ","address":"ニューヨーク","pets":[{"type":"犬","name":"ジョリー"},{"type":"猫","name":"グリザベラ"},{"type":"魚","name":"ニモ"}]}}

(5) Jacksonを使って、JSONを整形(Pretty Printing)して出力

このようにすると、JSONがインデントされキレイにフォーマットされて出てくる

ObjectMapper mapper2 = new ObjectMapper();
String prettyJson = mapper2.writerWithDefaultPrettyPrinter().writeValueAsString(model);
System.out.println(prettyJson);

実行結果

{
  "person" : {
    "firstName" : "ジョン",
    "lastName" : "ドゥ",
    "address" : "ニューヨーク",
    "pets" : [ {
      "type" : "犬",
      "name" : "ジョリー"
    }, {
      "type" : "猫",
      "name" : "グリザベラ"
    }, {
      "type" : "魚",
      "name" : "ニモ"
    } ]
  }
}

まとめ

  • GSONをつかってJSON→Java、Java→JSONをお手軽に実行する方法を説明しました

    • GSONを使ったソースコードはこちらです
  • Jacksonの場合も同様に説明しました

    • Jacksonを使ったソースコードはこちらです
  • JSONをHTTP通信でPOSTやGETする方法はこちらにまとめました

94
108
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
94
108

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?