【Java】JSON.simple(json-simple)の使い方

JSON.simple(json-simple)とは

JSON.simple(json-simple)は、JavaでJSONデータを簡単に操作できる軽量なライブラリです。
基本的なJSON操作には十分な機能が備わっています。

セットアップ

JSON.simpleを利用するには、プロジェクトに追加する必要があります。
MavenやGradleを使っている場合は、以下の方法で追加できます。

Mavenの場合

pom.xmlに下記を追加します。

<dependencies>
    <dependency>
        <groupId>com.googlecode.json-simple</groupId>
        <artifactId>json-simple</artifactId>
        <version>1.1.1</version>
    </dependency>
</dependencies>

Gradleの場合

build.gradleに下記を追加します。

dependencies {
    implementation 'com.googlecode.json-simple:json-simple:1.1.1'
}

JSONデータにエンコードする方法

JSONは、JavaのMapとListの形式で表現できます。Mapはキーと値の組み合わせで表現されたオブジェクトで、Listは複数の値を持つ配列です。

MapからJSONに変換

MapからJSONのオブジェクトを作成するにはJSONObjectを使用します。
JSONObjectはHashMapを継承したクラスとなっており、putメソッドで要素を追加することができます。

public class JsonSimpleExample1 {
    public static void main(String[] args) {
        JSONObject obj = new JSONObject();
        obj.put("name", "Taro Yamada");
        obj.put("age", 30);
        obj.put("weight", 67.8);
        obj.put("is_administrator", true);
        obj.put("nickname", null);
        System.out.println(obj);
    }
}

実行結果:

{"name":"Taro Yamada","nickname":null,"weight":67.8,"is_administrator":true,"age":30}

JSONObjectはHashMapであるため、内部で追加された順序を保持しておらず、JSONとして出力した際には、追加された順序で出力されない場合があります。

また、以下のようにJava標準のMapを介してJSONを生成することもできます。
LinkedHashMapを利用すれば、要素を追加した順にJSONとして出力されます。

import java.util.LinkedHashMap;
import java.util.Map;

import org.json.simple.JSONValue;

public class JsonSimpleExample2 {
    public static void main(String[] args) {
        Map<String, Object> obj = new LinkedHashMap<>();
        obj.put("name", "Taro Yamada");
        obj.put("age", 30);
        obj.put("weight", 67.8);
        obj.put("is_administrator", true);
        obj.put("nickname", null);
        String jsonText = JSONValue.toJSONString(obj);
        System.out.println(jsonText);
    }
}

実行結果:

{"name":"Taro Yamada","age":30,"weight":67.8,"is_administrator":true,"nickname":null}

ListからJSONに変換

ListからJSONの配列を作成するにはJSONArrayを使用します。
JSONArrayはArrayListを継承したクラスとなっており、addメソッドで要素を追加することができます。

public class JsonSimpleExample3 {
    public static void main(String[] args) {
        JSONArray list = new JSONArray();
        list.add("Taro Yamada");
        list.add(30);
        list.add(67.8);
        list.add(true);
        list.add(null);
        System.out.println(list);
    }
}

実行結果:

["Taro Yamada",30,67.8,true,null]

JSONArrayはListであるため、内部で順序を保持しており、JSONに変換した場合にも追加された順序に出力されることが保証されています。

また、以下のようにJava標準のListを介してJSONを生成することもできます。

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

import org.json.simple.JSONValue;

public class JsonSimpleExample4 {
    public static void main(String[] args) {
        List<Object> list = new ArrayList<>();
        list.add("Taro Yamada");
        list.add(30);
        list.add(67.8);
        list.add(true);
        list.add(null);
        String jsonText = JSONValue.toJSONString(list);
        System.out.println(jsonText);
    }
}

実行結果:

["Taro Yamada",30,67.8,true,null]

MapとListの組み合わせをJSONに変換

MapとListを組み合わせることで、ネストしたJSONを作成することもできます。

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;

public class JsonSimpleExample5 {
    public static void main(String[] args) {
        JSONObject obj1 = new JSONObject();
        JSONObject obj2 = new JSONObject();
        JSONArray list1 = new JSONArray();
        obj1.put("k1", "v1");
        obj1.put("k2", obj2);
        obj1.put("k3", list1);
        obj2.put("mk1", "mv1");
        list1.add("lv1");
        list1.add("lv2");
        obj2.put("mk2", list1);
        System.out.println(obj1);
    }
}

実行結果:

{"k1":"v1","k2":{"mk1":"mv1","mk2":["lv1","lv2"]},"k3":["lv1","lv2"]}

自作クラスをJSONに変換

自作したクラスにJSONAwareを実装することで、カスタマイズしたJSONを出力することができます。

import org.json.simple.JSONArray;
import org.json.simple.JSONAware;
import org.json.simple.JSONObject;

public class JsonSimpleExample6 {
    public static void main(String[] args) {
        JSONArray users = new JSONArray();
        users.add(new User(1, "foo1", "secret1"));
        users.add(new User(2, "foo2", "secret2"));
        users.add(new User(3, "foo3", "secret3"));
        System.out.println(users);
    }

    public static class User implements JSONAware {
        private int id;
        private String name;
        private String password;

        public User(int id, String name, String password) {
            this.id = id;
            this.name = name;
            this.password = password;
        }

        @Override
        public String toJSONString() {
            return "{\"userName\":\"" + JSONObject.escape(name) + "\",ID:" + id + "}";
        }
    }
}

実行結果:

[{"userName":"foo1",ID:1},{"userName":"foo2",ID:2},{"userName":"foo3",ID:3}]

Stringのフィールドを出力する場合には、JSONObjectクラスのescapeメソッドを使用して、エスケープする必要があります。

JSONデータからデコードする方法

JSONParserクラスのparseメソッドを使用することで、JSONをJSONObjectやJSONArray等のJavaのクラスに変換することができます。

JSONからMapに変換

JSONからJSONObjectに変換する例は以下になります。

public class JsonSimpleExample7 {
    public static void main(String[] args) {
        String jsonText = "{\"name\":\"Taro Yamada\",\"age\":30,\"weight\":67.8,\"is_administrator\":true,\"nickname\":null}";
        System.out.println(jsonText);

        JSONParser parser = new JSONParser();
        try {
            JSONObject obj = (JSONObject) parser.parse(jsonText);
            System.out.println("name: " + obj.get("name"));
            System.out.println("age: " + obj.get("age"));
            System.out.println("weight: " + obj.get("weight"));
            System.out.println("is_administrator: " + obj.get("is_administrator"));
            System.out.println("nickname: " + obj.get("nickname"));
        } catch (ParseException e) {
            System.err.println(e);
        }
    }
}

実行結果:

{"name":"Taro Yamada","age":30,"weight":67.8,"is_administrator":true,"nickname":null}
name: Taro Yamada
age: 30
weight: 67.8
is_administrator: true
nickname: null

JSONからListに変換

JSONからJSONArrayに変換する例は以下になります。

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

public class JsonSimpleExample8 {
    public static void main(String[] args) {
        String jsonText = "[{\"name\":\"Taro Yamada\",\"age\":30},{\"name\":\"Jiro Suzuki\",\"age\":28}]";
        System.out.println(jsonText);

        JSONParser parser = new JSONParser();
        try {
            JSONArray list = (JSONArray) parser.parse(jsonText);
            for (Object obj : list) {
                JSONObject jsonObject = (JSONObject) obj;
                System.out.println("name: " + jsonObject.get("name"));
                System.out.println("age: " + jsonObject.get("age"));
            }
        } catch (ParseException e) {
            System.err.println(e);
        }
    }
}

実行結果:

[{"name":"Taro Yamada","age":30},{"name":"Jiro Suzuki","age":28}]
name: Taro Yamada
age: 30
name: Jiro Suzuki
age: 28

デコード後の値の型について

下記コードでデコード後の値のJava型を確認します。

import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

public class JsonSimpleExample9 {
    public static void main(String[] args) {
        String jsonText = "{\"string\":\"foo\",\"int\":1,\"float\":2.3,\"bool\":true,\"obj\":{},\"list\":[]}";
        System.out.println(jsonText);

        JSONParser parser = new JSONParser();
        try {
            JSONObject obj = (JSONObject) parser.parse(jsonText);
            System.out.println("string: " + obj.get("string").getClass().getSimpleName());
            System.out.println("int: " + obj.get("int").getClass().getSimpleName());
            System.out.println("float: " + obj.get("float").getClass().getSimpleName());
            System.out.println("bool: " + obj.get("bool").getClass().getSimpleName());
            System.out.println("obj: " + obj.get("obj").getClass().getSimpleName());
            System.out.println("list: " + obj.get("list").getClass().getSimpleName());
        } catch (ParseException e) {
            System.err.println(e);
        }
    }
}

実行結果:

{"string":"foo","int":1,"float":2.3,"bool":true,"obj":{},"list":[]}
string: String
int: Long
float: Double
bool: Boolean
obj: JSONObject
list: JSONArray

デコード後の値のJava型について纏めると、以下の通りになります。

元データJava型補足説明
文字列StringString型にキャストするか、toStringメソッドで変換する
整数Longint型として扱いたい場合は、Long型にキャスト後、intValueメソッドを使用する
小数Doublefloat型として扱いたい場合は、Double型にキャスト後、floatValueメソッドを使用する
真偽値Booleanboolean型として扱いたい場合は、Boolean型にキャスト後、booleanValueメソッドを使用するか、直接boolean型にキャストする
JSONのオブジェクトJSONObjectデコード時点でJSONObject以外のMapとして扱いたい場合は、ContainerFactoryを使用する(下記参照
JSONの配列JSONArrayデコード時点でJSONArray以外のListとして扱いたい場合は、ContainerFactoryを使用する(下記参照

ContainerFactoryについて

デフォルトでは、JSONのオブジェクトはJSONObjectへと変換され、JSONの配列はJSONArrayへと変換されますが、ContainerFactoryを使用することで、任意のMapとListに変換することもできます。
下記コードは、LinkedHashMapとLinkedListに変換する例です。

import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.json.simple.parser.ContainerFactory;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

public class JsonSimpleExample10 {
    public static void main(String[] args) {
        String jsonText = "{\"obj\":{},\"list\":[]}";
        System.out.println(jsonText);

        ContainerFactory containerFactory = new ContainerFactory() {
            @Override
            public Map createObjectContainer() {
                return new LinkedHashMap<>();
            }

            @Override
            public List creatArrayContainer() {
                return new LinkedList<>();
            }
        };

        JSONParser parser = new JSONParser();
        try {
            Map<String, Object> obj = (Map<String, Object>) parser.parse(jsonText, containerFactory);
            System.out.println("obj: " + obj.get("obj").getClass().getSimpleName());
            System.out.println("list: " + obj.get("list").getClass().getSimpleName());
        } catch (ParseException e) {
            System.err.println(e);
        }
    }
}

実行結果:

{"obj":{},"list":[]}
obj: LinkedHashMap
list: LinkedList

まとめ

JSON.simpleについて解説しました。
JSON.simple以外だとJacksonやGsonなどの有名なライブラリがあります。これらのライブラリは、JSON.simpleよりも高機能で、パフォーマンスも優れている場合がありますが、初学者にはやや複雑であると感じることがあります。プロジェクトの要件や開発者の経験に応じて、適切なライブラリを選択してください。

最新情報をチェックしよう!