【Java】JSONとJavaオブジェクトの相互変換にはObjectMapperクラスを使おう【JSONの配列データにも対応】

JAVAのAPIの開発などで、

・「JSON」を「Javaオブジェクト」に変換する

または

・「Javaオブジェクト」を「JSON」に変換する

という実装をよく見かける。つまりJSONとjavaオブジェクト間の相互変換処理である。
しばらくすると実装方法を忘れてしまうため、備忘録のため実装方法をまとめておく。

# 実装のポイント
ポイントは以下のとおり。

1. JSONとJavaオブジェクトの相互変換にはObjectMapperクラスを利用する。
2. 「JSON」から 「Javaオブジェクト」への変換時は「readValue」メソッドを使用して変換する。
3. 「Javaオブジェクト」から「JSON」への変換時は「writeValueAsString」メソッドを使用して変換する。

# ケース1.JSONデータ → Javaオブジェクトへの変換
まずはJSONデータからJavaオブジェクトへの変換処理についてまとめる。
例として配列構造を含むJSONを変換してみる。
```json
{
	"id": 10,
	"title": "ユーザー情報",
	"userInfo": [
		{
			"name": "ジョジョ",
			"age": 30
		},
		{
			"name": "DIO",
			"age": 35
		}
	]
}
```

## 変換用のクラスを用意する
変換対象となるJSONデータのプロパティ名と、同一のフィールド名を用意したクラスを作る。
配列構造となる部分は、UserInfo型のフィールドを用意することで対応する。

```java
/**
 * lombokでGetterとSetterを用意する.
 */
@Data
public class JsonConverter {

    private Long id;

    private String title;

    private List<UserInfo> userInfos;

    /**
     * JSONの配列部分を変換するためのクラス.
     * インスタンス化しないで使えるようにstaticをつけておく.
     */
    @Data
    public static class UserInfo {

        private String name;

        private Integer age;
    }
}
```
事前準備は以上で終了。変換処理にはObjectMapperというクラスを利用する。


## JSONとJavaオブジェクトを相互に変換できるObjectMapperクラス
ObjectMapperクラスはJSON文字列とJavaオブジェクトを相互に変換できる。
このクラスにある「readValue」というメソッドを使用して変換処理を行うことになる。

```java
     /**
     * JSON文字列をjavaオブジェクトに変換します.
     */
    @GetMapping("/convert/object")
    public void JsonConvertToObject(){

        // 文字列型のJSONを用意
        String jsonStr = "{\n" +
                "\t\"id\": 10,\n" +
                "\t\"title\": \"ユーザー情報\",\n" +
                "\t\"userInfos\": [\n" +
                "\t\t{\n" +
                "\t\t\t\"name\": \"ジョジョ\",\n" +
                "\t\t\t\"age\": 30\n" +
                "\t\t},\n" +
                "\t\t{\n" +
                "\t\t\t\"name\": \"DIO\",\n" +
                "\t\t\t\"age\": 35\n" +
                "\t\t}\n" +
                "\t]\n" +
                "}\n";



        // 上のjson文字列をオブジェクトに変換するためObjectMapperを用意する.
        ObjectMapper mapper = new ObjectMapper();

        // 変換はObjectMapperクラスのreadValueメソッドを使用する.
        // readValueメソッドでの変換時はtry 〜 catchで囲む必要あり.
        JsonConverter jsonConverter;
        try {

            // objectMapperクラスのreadValueメソッドを使用してオブジェクトに変換する.
            // 2つ目の引数に変換するクラスの型を指定する.
            jsonConverter = mapper.readValue(jsonStr, JsonConverter.class);

        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }

        // オブジェクト変換後に値を出力する.
        System.out.println("id: " + jsonConverter.getId());
        System.out.println("title: " + jsonConverter.getTitle());

        // 配列処理でユーザー情報(userInfo)の値をそれぞれ出力する
        for (JsonConverter.UserInfo userInfo :jsonConverter.getUserInfos()) {
            System.out.println("name: " + userInfo.getName());
            System.out.println("age: " + userInfo.getAge());
        }
    }
```

出力結果は以下のとおり。
```terminal
id: 10
title: ユーザー情報
name: ジョジョ
age: 30
name: DIO
age: 35
```

# ケース2.Javaオブジェクト → JSONデータへの変換
JavaオブジェクトからJSONデータに変換する場合も、流れはほぼ同じである。
ObjectMapperクラスを使用して変換を行うが、利用するメソッドが異なり、「writeValueAsString」メソッドを利用することで変換が可能となる。

実装は以下のとおり。
```java
    @GetMapping("/convert/json")
    public void ObjectConvertToJson(){

        // JSONに変換するオブジェクトを用意
        JsonConverter jsonConverter = new JsonConverter();
        jsonConverter.setId(100L);
        jsonConverter.setTitle("JAVAオブジェクトからJSONへ変換");

        // UserInfo型の配列を用意する.
        List<JsonConverter.UserInfo> userInfos = new ArrayList<JsonConverter.UserInfo>();

        // 配列に加える要素を用意する.
        JsonConverter.UserInfo userInfo = new JsonConverter.UserInfo();
        userInfo.setName("ジョジョ");
        userInfo.setAge(30);

        JsonConverter.UserInfo userInfo2 = new JsonConverter.UserInfo();
        userInfo2.setName("DIO");
        userInfo2.setAge(35);

        userInfos.add(userInfo);
        userInfos.add(userInfo2);
        // 作成したユーザー情報をフィールドに加える.
        jsonConverter.setUserInfos(userInfos);


        
        // オブジェクトからJSONに変換するためObjectMapperをインスタンス化する.
        // 「.enable()...」 以降はJSONデータをコンソール出力する際、見やすく改行した状態で出力するための呪文.
        ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);

        // オブジェクトからJSONに変換する場合は`writeValueAsString`メソッドを利用する.
        String json;
        try {
            // writeValueAsStringメソッドでJavaオブジェクトをJSONに変換する.
            json = mapper.writeValueAsString(jsonConverter);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }

        // 変換結果を出力する.
        System.out.println(json);
    }
```

結果は以下のとおり。
```terminal
{
  "id" : 100,
  "title" : "JAVAオブジェクトからJSONへ変換",
  "userInfos" : [ {
    "name" : "ジョジョ",
    "age" : 30
  }, {
    "name" : "DIO",
    "age" : 35
  } ]
}
```

参考になれば幸いです！！