JacksonでJSONを操ろう!

docs

前回は「デザインパターン」について学んだよね。オブジェクト指向の考え方をさらに深めて、プログラムの設計をより良くするための「お作法」があるって話だったね。

デザインパターンってなんだろう? | ToolDocs

今回は、実際のJavaアプリケーション開発でめちゃくちゃよく使う、ある強力なライブラリについて解説していくよ! それが「Jackson(ジャクソン)」だ!


Jacksonってなんだろう?

最近のWebアプリケーション開発では、違うシステム同士がデータをやり取りするのに「JSON(ジェイソン)」っていう形式がよく使われるんだ。JSONは、JavaScript Object Notationの略で、人間が読んで理解しやすく、コンピュータにとっても扱いやすいデータ形式なんだよ。

例えば、こんな感じのデータを見たことないかな?

JSON

{
  "name": "タマ",
  "age": 3,
  "breed": "三毛猫",
  "hobbies": ["昼寝", "ご飯", "いたずら"]
}

これは、「タマ」っていう猫の情報が書かれているJSONデータだね。名前が「タマ」で、年齢が「3歳」、種類が「三毛猫」、趣味は「昼寝」「ご飯」「いたずら」ってのが一目でわかるよね。

さて、JavaのプログラムでこのJSONデータを扱いたいとき、どうすると思う? 手動で文字列をパース(解析)して、必要な情報を取り出すのは、すごく大変だし、ミスも起きやすいよね。

そこで登場するのが「Jackson」だ! Jacksonは、JavaのオブジェクトとJSONデータの変換を、ものすごーく簡単にしてくれるライブラリなんだ。Javaの世界では、もうデファクトスタンダード(事実上の標準)って言ってもいいくらい、広く使われているよ。


Jacksonが解決してくれること

Jacksonを使うと、主に次の2つのことができるようになるんだ。

  1. Javaオブジェクト → JSON文字列に変換(シリアライズ) Javaのクラスのインスタンスを、JSON形式の文字列に変換することだよ。例えば、CatというJavaクラスのインスタンスをJSONとしてWebサービスに送りたいときに使うよ。
  2. JSON文字列 → Javaオブジェクトに変換(デシリアライズ) JSON形式の文字列を、Javaのクラスのインスタンスに変換することだよ。例えば、WebサービスからJSONデータを受け取って、Javaのプログラムで扱いやすいオブジェクトの形にしたいときに使うよ。

Jacksonを使ってみよう!

じゃあ、実際にJacksonを使って、どうやってJavaオブジェクトとJSONを変換するのか見ていこう!

まずは、Jacksonを使うための準備から。プロジェクトにJacksonのライブラリを追加する必要があるんだ。Mavenを使っているなら、pom.xmlに次のように追加するよ。

XML

<dependencies>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.17.1</version> 
    </dependency>
</dependencies>

jackson-databindを追加すれば、他の必要なJacksonのモジュール(jackson-core, jackson-annotationsなど)も自動的に含まれるよ。

例1:JavaオブジェクトをJSONに変換(シリアライズ)

まず、JSONに変換したいJavaのクラスを定義するよ。POJO(Plain Old Java Object)って呼ばれる、データを持つだけのシンプルなクラスが一般的だね。

Java

// Cat.java
public class Cat {
    private String name;
    private int age;
    private String breed;
    private java.util.List<String> hobbies;

    // コンストラクタ(Jacksonがデシリアライズする際に必要)
    public Cat() {
    }

    public Cat(String name, int age, String breed, java.util.List<String> hobbies) {
        this.name = name;
        this.age = age;
        this.breed = breed;
        this.hobbies = hobbies;
    }

    // getterとsetter(Jacksonがプロパティにアクセスするために必要)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getBreed() {
        return breed;
    }

    public void setBreed(String breed) {
        this.breed = breed;
    }

    public java.util.List<String> getHobbies() {
        return hobbies;
    }

    public void setHobbies(java.util.List<String> hobbies) {
        this.hobbies = hobbies;
    }

    @Override
    public String toString() {
        return "Cat{" +
               "name='" + name + '\'' +
               ", age=" + age +
               ", breed='" + breed + '\'' +
               ", hobbies=" + hobbies +
               '}';
    }
}

次に、このCatオブジェクトをJSON文字列に変換するコードを見てみよう。

Java

import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Arrays;

public class SerializeExample {
    public static void main(String[] args) {
        // 1. ObjectMapperのインスタンスを作成
        ObjectMapper objectMapper = new ObjectMapper();

        // 2. 変換したいJavaオブジェクトを作成
        Cat tama = new Cat("タマ", 3, "三毛猫", Arrays.asList("昼寝", "ご飯", "いたずら"));

        try {
            // 3. writeValueAsString()メソッドでJSON文字列に変換
            String jsonString = objectMapper.writeValueAsString(tama);

            System.out.println("JavaオブジェクトからJSON文字列へ変換:");
            System.out.println(jsonString);

        } catch (com.fasterxml.jackson.core.JsonProcessingException e) {
            e.printStackTrace();
        }
    }
}

これを実行すると、次のようなJSON文字列が出力されるはずだよ。

JSON

JavaオブジェクトからJSON文字列へ変換:
{"name":"タマ"
,"age":3
,"breed":"三毛猫"
,"hobbies":["昼寝","ご飯","いたずら"]}

どう? 簡単だよね! ObjectMapperwriteValueAsString()メソッドにJavaオブジェクトを渡すだけで、JSON文字列が手に入るんだ。

例2:JSON文字列をJavaオブジェクトに変換(デシリアライズ)

今度は逆に、JSON文字列からJavaオブジェクトに変換する例を見てみよう。

Java

import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Arrays;

public class DeserializeExample {
    public static void main(String[] args) {
        // 1. ObjectMapperのインスタンスを作成
        ObjectMapper objectMapper = new ObjectMapper();

        // 2. 変換したいJSON文字列を用意
        String jsonString = "{\"name\":\"ポチ\",\"age\":5,\"breed\":\"柴犬\",\"hobbies\":[\"散歩\",\"ボール遊び\"]}";

        try {
            // 3. readValue()メソッドでJavaオブジェクトに変換
            //    第1引数にJSON文字列、第2引数に変換したいクラスのClassオブジェクトを指定
            Cat pochi = objectMapper.readValue(jsonString, Cat.class);

            System.out.println("\nJSON文字列からJavaオブジェクトへ変換:");
            System.out.println("名前: " + pochi.getName());
            System.out.println("年齢: " + pochi.getAge());
            System.out.println("種類: " + pochi.getBreed());
            System.out.println("趣味: " + pochi.getHobbies());
            System.out.println(pochi); // toString()メソッドでオブジェクト全体を確認

        } catch (com.fasterxml.jackson.core.JsonProcessingException e) {
            e.printStackTrace();
        }
    }
}

これを実行すると、JSON文字列がJavaのCatオブジェクトに正しく変換されているのがわかるはずだよ。

JSON文字列からJavaオブジェクトへ変換:
名前: ポチ
年齢: 5
種類: 柴犬
趣味: [散歩, ボール遊び]

Cat{name='ポチ'
, age=5
, breed='柴犬'
, hobbies=[散歩, ボール遊び]}

ObjectMapperreadValue()メソッドを使うことで、JSON文字列が自動的にCatクラスのインスタンスにマッピングされるんだ。これめちゃくちゃ便利だよね!


もっと高度な使い方 (アノテーション)

Jacksonは、デフォルトの動作でも十分便利なんだけど、もっと細かく変換ルールを制御したいときに「アノテーション」を使うことができるんだ。アノテーションは、Javaのコードにメタデータ(付加情報)を追加するための特別な記法だよ。

例えば、

  • JSONのキー名とJavaのフィールド名が違う場合
  • 特定のフィールドをJSONに含めたくない場合
  • 日付のフォーマットを指定したい場合

なんかにアノテーションが役立つんだ。

例3:@JsonPropertyでキー名を変更

JSONのキー名をJavaのフィールド名と変えたい場合は、@JsonPropertyアノテーションを使うよ。

Java

// Dog.java
import com.fasterxml.jackson.annotation.JsonProperty;

public class Dog {
    @JsonProperty("dog_name") // JSONでは"dog_name"だけど、Javaでは"name"として扱う
    private String name;
    private int age;

    public Dog() {
    }

    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

Java

import com.fasterxml.jackson.databind.ObjectMapper;

public class JsonPropertyExample {
    public static void main(String[] args) {
        ObjectMapper objectMapper = new ObjectMapper();

        // シリアライズの例
        Dog jiro = new Dog("ジロー", 7);
        try {
            String jsonOutput = objectMapper.writeValueAsString(jiro);
            System.out.println("シリアライズ (@JsonProperty): " + jsonOutput);
            // 出力例: {"dog_name":"ジロー","age":7}
        } catch (Exception e) {
            e.printStackTrace();
        }

        // デシリアライズの例
        String jsonInput = "{\"dog_name\":\"ハナコ\",\"age\":2}";
        try {
            Dog hanako = objectMapper.readValue(jsonInput, Dog.class);
            System.out.println("デシリアライズ (@JsonProperty):");
            System.out.println("名前: " + hanako.getName() + ", 年齢: " + hanako.getAge());
            // 出力例: 名前: ハナコ, 年齢: 2
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

@JsonProperty("dog_name")nameフィールドに付けることで、JSON変換時にはdog_nameというキー名になるけど、Javaのコードではnameとして扱えるようになるんだ。これ、外部システムとの連携でJSONのキー名が固定されている場合なんかに、すごく便利なんだよ。

他にも、@JsonIgnoreでJSONに含めたくないフィールドを指定したり、@JsonFormatで日付の形式を指定したりと、たくさんのアノテーションがあるから、必要になったら調べてみてね。


まとめ

今回はJava開発で欠かせないライブラリ「Jackson」について学んだよ。

  • Jacksonは、JavaオブジェクトとJSONデータの相互変換(シリアライズとデシリアライズ)を簡単にしてくれる強力なライブラリ。
  • ObjectMapperを使って、writeValueAsString()でJava → JSONreadValue()でJSON → Javaの変換ができる。
  • @JsonPropertyのようなアノテーションを使うことで、変換のルールをより細かく制御できる。

Webアプリケーション開発、特にRESTful APIを作る際には、ほぼ確実にJacksonを使うことになると思うから、今のうちに基本的な使い方をマスターしておくと、今後の学習がすごく楽になるよ!


次回の記事も読んでくれると嬉しいな!

コメント

タイトルとURLをコピーしました