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型 | 補足説明 |
---|---|---|
文字列 | String | String型にキャストするか、toStringメソッドで変換する |
整数 | Long | int型として扱いたい場合は、Long型にキャスト後、intValueメソッドを使用する |
小数 | Double | float型として扱いたい場合は、Double型にキャスト後、floatValueメソッドを使用する |
真偽値 | Boolean | boolean型として扱いたい場合は、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よりも高機能で、パフォーマンスも優れている場合がありますが、初学者にはやや複雑であると感じることがあります。プロジェクトの要件や開発者の経験に応じて、適切なライブラリを選択してください。