Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
33
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

Jacksonで配列JSONをJavaBeanの配列又はListに変換する

Jacksonを使用して配列JSONを、任意のJavaBean配列やjava.util.List<T>として読み込む方法を紹介します。

今回は、以下のようなJSONをJavaBean(Todo)の配列やリストにマッピングして読み込みます。

  • 配列JSON
[
  {
    "title" : "Jsckson勉強会"
  }
  ,
  {
    "title" : "飲み会"
  }
]
  • JavaBean(Todo)
public class Todo {
    private String title;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}

動作検証バージョン

  • Jackson 2.6.7
  • Spring Boot 1.3.6.RELEASE

検証コード

JSONを読み込む

実際にJunitを作って動かしてみます。なお、Junitで作っていますが、今回はAssertは省略させてもらいます。

package com.example;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;


public class ObjectMapperJsonArrayTests {

    private static final String ARRAY_JSON = new StringBuilder()
            .append("[")
            .append("  {")
            .append("    \"title\" : \"Jsckson勉強会\"")
            .append("  }")
            .append("  ,")
            .append("  {")
            .append("    \"title\" : \"飲み会\"")
            .append("  }")
            .append("]").toString();

    private final ObjectMapper jsonMapper = new ObjectMapper();

    /**
     * 配列として読み込む
     */
    @Test
    public void array() throws IOException {
        Todo[] todoArray = jsonMapper.readValue(ARRAY_JSON, Todo[].class);
        for (Todo todo : todoArray) {
            System.out.println(todo.getTitle());
        }
    }

    /**
     * 配列として読み込みArrays#asListでリスト化する
     */
    @Test
    public void arrayConvertListUsingArraysAsList() throws IOException {
        List<Todo> todoList = Arrays.asList(jsonMapper.readValue(ARRAY_JSON, Todo[].class));
        for (Todo todo : todoList) {
            System.out.println(todo.getTitle());
        }
    }

    /**
     * TypeReferenceを使用してリストとして読み込む
     */
    @Test
    public void listUsingTypeReference() throws IOException {
        List<Todo> todoList = jsonMapper.readValue(ARRAY_JSON, new TypeReference<List<Todo>>() {});
        for (Todo todo : todoList) {
            System.out.println(todo.getTitle());
        }
    }

    static class Todo {
        private String title;

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }
    }

}

このテストケースを実行すると・・・

コンソール
Jsckson勉強会
飲み会
Jsckson勉強会
飲み会
Jsckson勉強会
飲み会

という感じで標準出力に読み込んだ内容が出力されます。

配列として読み込む

一番シンプルな読み込み方法です。メソッド内の処理だけで使う+拡張For文などで単純な繰り返し処理を行うだけなら配列でもよいと思います。

Todo[] todoArray = jsonMapper.readValue(ARRAY_JSON, Todo[].class);

配列として読み込みArrays#asListでリスト化する

読み込んだ配列をメソッドの返り値として返却するような場合は、配列ではなくリストを使うのが一般的でしょう。そんな時は、java.util.Arrays#asList(T...)を使うと簡単にリスト化できます。なお、この方法でリスト化すると、リストに対して要素の追加や削除などができないリストが生成されます。(要素を追加、削除するとjava.lang.UnsupportedOperationExceptionが発生します)

List<Todo> todoList = Arrays.asList(jsonMapper.readValue(ARRAY_JSON, Todo[].class));

TypeReferenceを使用してリストとして読み込む

リストとして読み込む方法もあります。リストとして読み込む場合は、読み込みたい型をcom.fasterxml.jackson.core.type.TypeReferenceの型パラメータに指定します。この方法で生成したリストに対しては、要素の追加や削除もできます。

List<Todo> todoList = jsonMapper.readValue(ARRAY_JSON, new TypeReference<List<Todo>>() {});

まとめ

本投稿では3つの方法(配列方式、配列->リスト変換方式、リスト方式)を紹介しました。
これは個人的な意見ですが、TypeReference方式はなんとなく直感的じゃない気がしてあまり好きじゃない・・・。初見だと・・・TypeReferenceって何者だろ〜と思う方もいるのでは???
であれば、Javaの標準APIを使ってリスト化する方がわかりやすいと思います。(あくまで個人的な意見です。 :wink:

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
33
Help us understand the problem. What are the problem?