本ページはプロモーションが含まれています

Java入門

【Java JSON変換】ライブラリ(Jackson/Gson)を徹底解説!

トム

・都内自社開発IT企業勤務/javaのバックエンドエンジニア
/java歴10年以上 ・首都圏在住30代
・資格:基本情報技術者/応用情報技術者/Java Silver/Python3エンジニア認定基礎

「JavaでWeb APIから受け取ったJSONをどう扱えばいいの?」

「設定ファイルをJSONで管理したいけど、どのライブラリを選べばいいかわからない…」

Javaでの開発において、JSON (JavaScript Object Notation) の扱いは避けて通れません。私自身もJavaエンジニアとしてキャリアをスタートした頃、どのJSON変換ライブラリを使うべきか、頻繁に発生するエラーにどう対処すれば良いか、多くの時間を費やした経験があります。

この記事を最後まで読めば、あなたが得られることは以下の3つです。

  1. JSONの基本から、Javaでの扱い方までを体系的に理解できる
  2. Jackson、Gson、org.json という3大ライブラリの特徴と具体的な使い方をマスターできる
  3. よくあるエラーの原因と解決策がわかり、開発効率が格段にアップする

JSONとは?Javaで扱う前に知っておきたい基礎

最初に、JSONそのものについて簡単におさらいします。JSONは「JavaScript Object Notation」の略で、テキストベースの非常に軽量なデータ交換フォーマットです。

人間にとってもプログラムにとっても読み書きがしやすいため、Web APIでのデータ通信や設定ファイルなど、幅広い用途で利用されています。

JSONの基本的な構造(オブジェクトと配列)

JSONの構造は、たった2つの基本ルールで成り立っています。

ルール

  1. オブジェクト: {} (波括弧) で囲まれ、"キー": 値 のペアがカンマで区切られた集まりです。他のプログラミング言語におけるマップや連想配列に似ています。
  2. 配列: [] 角括弧)で囲まれ、値がカンマで区切られたリストです。

これらを組み合わせることで、複雑なデータ構造も表現できます。

{
  "name": "山田 太郎",
  "age": 30,
  "isMarried": true,
  "skills": [
    {
      "language": "Java",
      "experience": 5
    },
    {
      "language": "Python",
      "experience": 2
    }
  ]
}

この例では、全体が1つのオブジェクトです。nameage といったキーに対して文字列や数値が設定され、skills キーにはオブジェクトを要素に持つ配列が設定されています。

XMLとの違いとメリット

JSONと比較されるフォーマットにXMLがあります。昔はXMLが主流でしたが、現在では多くの場面でJSONが選ばれるようになりました。

項目JSONXML
記法{}[] を使うシンプルな構造タグで囲む冗長な構造
可読性人間が読みやすいタグが多く読みにくいことがある
データ量軽量でデータ量が少ない終了タグが必要なためデータ量が多くなる
パース速度高速比較的遅い

このように、JSONは シンプル・軽量・高速 というメリットがあり、特にWebアプリケーションとの相性が抜群です。

JavaでJSONを扱う方法の全体像

Javaの標準APIには、JSONを直接的に扱うための便利な機能が含まれていません。そのため、JavaでJSON変換を行うには、専門のライブラリを利用するのが一般的です。

JSON変換の代表的なライブラリ

JavaのJSON変換ライブラリは数多く存在しますが、特に広く使われているのが以下の3つです。

ライブラリ

  • Jackson: 事実上の標準(デファクトスタンダード)です。非常に高機能かつ高性能で、Spring Bootなどのフレームワークでは標準で採用されています。
  • Gson: Googleが開発したライブラリです。シンプルなAPIで直感的に使いやすく、Android開発などで人気があります。
  • org.json: 軽量で依存関係が少ないのが特徴です。サードパーティライブラリをあまり追加したくない場合や、簡単なJSON操作に適しています。

String ⇔ JSON変換の基本的な流れ

JavaでのJSON変換の基本的な処理は、次の2つの方向性があります。

  1. シリアライズ(Javaオブジェクト → JSON文字列): Javaのオブジェクトを、APIで送信したりファイルに保存したりできるJSON形式の文字列に変換します。
  2. デシリアライズ(JSON文字列 → Javaオブジェクト): APIから受け取ったJSON形式の文字列や、ファイルから読み込んだJSON文字列を、Javaのプログラムで扱えるオブジェクトに変換します。

この2つの変換をいかにスムーズに行えるかが、ライブラリ選定の重要なポイントになります。

Jacksonを使ったJSON変換

ここでは、最も人気のある Jackson を使ったJSON変換の方法を解説します。多くのJavaプロジェクトで採用実績があり、まず最初に習得すべきライブラリといえるでしょう。

Mavenを使用している場合、pom.xml に以下の依存関係を追加します。

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

オブジェクトをJSONに変換する(シリアライズ)

JavaオブジェクトをJSON文字列に変換するには、ObjectMapper クラスの writeValueAsString() メソッドを使います。

まず、変換対象となるJavaクラス(POJO)を定義します。

public class User {
    private int id;
    private String name;

    // コンストラクタ、ゲッター、セッターは省略
}

次に、このUserオブジェクトをJSONに変換します。

import com.fasterxml.jackson.databind.ObjectMapper;

public class Main {
    public static void main(String[] args) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        User user = new User(1, "佐藤 一郎");

        // JavaオブジェクトをJSON文字列に変換
        String json = objectMapper.writeValueAsString(user);

        System.out.println(json); 
        // 出力: {"id":1,"name":"佐藤 一郎"}
    }
}

たったこれだけで、JavaオブジェクトをJSON文字列に変換できました。

JSONをオブジェクトに変換する(デシリアライズ)

逆に、JSON文字列をJavaオブジェクトに変換するには readValue() メソッドを使用します。

import com.fasterxml.jackson.databind.ObjectMapper;

public class Main {
    public static void main(String[] args) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        String json = "{\"id\":2,\"name\":\"鈴木 花子\"}";

        // JSON文字列をUserオブジェクトに変換
        User user = objectMapper.readValue(json, User.class);

        System.out.println(user.getName()); // 出力: 鈴木 花子
    }
}

readValue() の第2引数に変換先のクラスを指定するだけで、自動的にマッピングしてくれます。非常に直感的ですね。

アノテーションで変換ルールをカスタマイズ

Jacksonの強力な機能の1つが、アノテーションを使った柔軟なカスタマイズです。いくつか代表的なものを紹介します。

  • @JsonProperty("json_key_name"): JSONのキー名とJavaのフィールド名を個別に指定できます。
  • @JsonIgnore: 特定のフィールドをJSON変換の対象外にします。
  • @JsonFormat(pattern = "yyyy-MM-dd"): 日付型のフォーマットを指定できます。
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Date;

public class Book {
    @JsonProperty("book_id")
    private int id;
    
    private String title;
    
    @JsonIgnore
    private String internalMemo; // このフィールドはJSONに出力されない

    // 省略
}

このようにアノテーションを使うことで、コードの可読性を保ちながら変換ルールを細かく制御可能です。

Gsonを使ったJSON変換

次に、Google製のライブラリ Gson を見ていきましょう。シンプルさが魅力で、手軽にJSON変換を始めたい場合におすすめです。

pom.xml に以下の依存関係を追加します。

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.10.1</version>
</dependency>

Gsonでのシンプルな変換例

Gsonでの変換は Gson クラスのインスタンスを使います。

import com.google.gson.Gson;

public class Main {
    public static void main(String[] args) {
        Gson gson = new Gson();
        User user = new User(1, "高橋 三郎");

        // シリアライズ: Javaオブジェクト → JSON
        String json = gson.toJson(user);
        System.out.println(json); // 出力: {"id":1,"name":"高橋 三郎"}

        // デシリアライズ: JSON → Javaオブジェクト
        String inputJson = "{\"id\":2,\"name\":\"田中 由美\"}";
        User user2 = gson.fromJson(inputJson, User.class);
        System.out.println(user2.getName()); // 出力: 田中 由美
    }
}

Jacksonと似ていますが、toJson()fromJson() という分かりやすいメソッド名で、よりシンプルに記述できます。

カスタムフォーマット・型アダプタの使い方

Gsonでも、TypeAdapter を使うことで特殊なデータ型の変換ルールを定義できます。例えば、特定のクラスを常に大文字の文字列としてシリアライズしたい、といったカスタマイズが可能です。少し応用的な内容ですが、柔軟な変換を実現できる強力な機能です。

org.jsonを使った軽量な変換

org.jsonは、オブジェクトマッピング機能を持たない、より低レベルな操作を提供するライブラリです。POJOクラスを定義せずに、動的にJSONを組み立てたり、値を取得したりする場合に便利です。

pom.xml への記述例です。

<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20230227</version>
</dependency>

JSONObjectとJSONArrayの基本操作

JSONObject はマップのようにキーと値でデータを保持し、JSONArray はリストのように値を順序付けて保持します。

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

public class Main {
    public static void main(String[] args) {
        // JSONオブジェクトの作成
        JSONObject user = new JSONObject();
        user.put("id", 1);
        user.put("name", "渡辺 四郎");

        // JSONArrayの作成
        JSONArray skills = new JSONArray();
        skills.put("Java");
        skills.put("SQL");

        user.put("skills", skills);

        System.out.println(user.toString(2)); // インデント付きで出力
    }
}

手軽に値を取り出す・書き込む方法

put() メソッドで値を書き込み、getString()getInt() などの型付けされたgetメソッドで安全に値を取り出せます。

String jsonStr = "{\"id\":10,\"name\":\"伊藤 五月\"}";
JSONObject obj = new JSONObject(jsonStr);

int id = obj.getInt("id");
String name = obj.getString("name");

System.out.println("ID: " + id + ", Name: " + name);

オブジェクトマッピングの手間がない分、手軽にJSONデータを直接操作できるのがメリットです。

JSON変換の実践テクニック

ここでは、より複雑なデータ構造を扱うためのテクニックを紹介します。

ネストされたJSONの扱い方

JSONのオブジェクトが入れ子になっている場合、Java側もクラスを入れ子にして定義することで、JacksonやGsonで簡単にマッピングできます。

{
  "orderId": "A-001",
  "customer": {
    "name": "鈴木 一郎",
    "address": "東京都..."
  }
}

このJSONに対応するJavaクラスは以下のようになります。

public class Order {
    private String orderId;
    private Customer customer;
    // getter, setter
}

public class Customer {
    private String name;
    private String address;
    // getter, setter
}

ListやMapとの相互変換

List<User> のようなコレクションも、ライブラリが自動的にJSON配列に変換してくれます。逆にJSON配列から List<User> のようなジェネリクスを使った型にデシリアライズするには、少し工夫が必要です。

Jacksonでは TypeReference を使って、型情報を実行時に保持したまま安全に変換できます。

String jsonArray = "[{\"id\":1}, {\"id\":2}]";
List<User> userList = objectMapper.readValue(jsonArray, new TypeReference<List<User>>(){});

Null値やOptionalの処理

デフォルトでは、JavaオブジェクトのnullフィールドはJSONにも"fieldName": nullとして出力されます。これを出力しないようにするには、Jacksonで以下のように設定します。

objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

また、Java 8以降で導入されたOptionalを正しく扱うには、jackson-datatype-jdk8のような専用モジュールを追加すると便利です。

あわせて読む

よくあるエラーと解決方法

最後に、JavaのJSON変換で初心者がつまずきがちなエラーとその解決策を紹介します。

型不一致エラー

JSONでは "age": "20" のように数値が文字列で表現されることがあります。Java側でint age;のように数値型で受け取ろうとすると、型不一致エラーが発生します。

解決策: JSONの形式に合わせてJavaクラスのフィールドの型をStringにするか、 lenient(寛容な)モードを持つライブラリ設定を利用します。

JSONパース時の例外

JSONの構文が正しくない(例:カンマが抜けている、括弧が閉じていない)場合に発生します。

解決策: エラーメッセージをよく読み、どの部分でパースに失敗したかを確認します。オンラインのJSONバリデーターなどで構文をチェックするのも有効です。

文字コードや日本語処理の注意点

ファイルからJSONを読み込んだり、HTTPレスポンスで受け取ったりする際に日本語が文字化けすることがあります。

解決策: データの入力・出力時には、文字コードをUTF-8に明確に指定しましょう。InputStreamReaderなどを使う際に文字コードを指定することで、多くの文字化け問題を防げます。

まとめ|JavaでのJSON変換を使いこなそう

この記事では、JavaにおけるJSON変換の基本から、3大ライブラリ(Jackson, Gson, org.json)の使い方、実践的なテクニック、そしてよくあるエラーまでを網羅的に解説しました。

初心者におすすめのライブラリ

もし、どのライブラリを使うか迷ったら、まずは Jackson から始めてみることを強くおすすめします。

理由は、Spring Bootの標準ライブラリであり、Web上の情報量も圧倒的に多いからです。高機能で柔軟性も高いため、Jacksonを使いこなせれば、ほとんどの要件に対応できます。

プロジェクト規模に応じた選び方

最後に、プロジェクトの特性に応じたライブラリの選び方をまとめます。

  • 中〜大規模なWebアプリケーション開発: Jackson が最適です。豊富なアノテーションと高いパフォーマンスが魅力。
  • Android開発やシンプルなツール: Gson が扱いやすいでしょう。直感的なAPIで学習コストが低いです。
  • 依存関係を増やしたくない、簡単なJSON操作: org.json が役立ちます。手軽にJSONを構築・解析したい場合に便利です。

JavaでのJSON変換は、現代のアプリケーション開発に必須のスキルです。この記事を参考に、ぜひJSON変換をマスターして、あなたの開発プロジェクトに活かしてください。

  • この記事を書いた人
  • 最新記事

トム

・都内自社開発IT企業勤務/javaのバックエンドエンジニア
/java歴10年以上 ・首都圏在住30代
・資格:基本情報技術者/応用情報技術者/Java Silver/Python3エンジニア認定基礎

-Java入門