LoginSignup
3
1

More than 3 years have passed since last update.

Jackson で Java Enum 列挙型と JSON をシリアライズ・デシリアライズするサンプルコード

Posted at

概要

  • Java Enum 列挙型と JSON 内の値を相互変換する
  • Jackson の提供する抽象クラス JsonSerializer と JsonDeserializer を使う

動作確認環境

  • Java 11 (AdoptOpenJDK 11.0.6+10)
  • Jackson Databind 2.10.3
  • Gradle 6.2.1
  • macOS Catalina

サンプルコード

package com.example.humansex;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

import java.io.IOException;

/**
 * ISO 5218 (ヒトの性別の表記のためのコード) を表す列挙型です。
 * 性別コード: 不明=0, 男性=1, 女性=2, 適用不能=9
 */
public enum HumanSex {

  /**
   * 不明=0, 男性=1, 女性=2, 適用不能=9
   */
  NOT_KNOWN(0), MALE(1), FEMALE(2), NOT_APPLICABLE(9);

  private final int code;

  private HumanSex(int code) {
    this.code = code;
  }

  /**
   * 性別コードを返します。
   */
  public int getCode() {
    return code;
  }

  /**
   * 性別コードに合致する HumanSex 列挙定数を返します。
   *
   * @param code 性別コード
   * @return HumanSex 列挙定数
   */
  public static HumanSex codeOf(int code) {
    for (HumanSex value : HumanSex.values()) {
      if (code == value.getCode()) {
        return value;
      }
    }
    return null; // 合致せず
  }

  /**
   * HumanSex オブジェクトを JSON にシリアライズするクラスです。
   */
  public static class Serializer extends JsonSerializer<HumanSex> {

    /**
     * JSON 生成時に HumanSex オブジェクトを性別コード(整数値)に変換します。
     */
    @Override
    public void serialize(HumanSex value, JsonGenerator generator, SerializerProvider serializers) throws IOException {
      generator.writeNumber(value.getCode());
    }
  }

  /**
   * JSON から HumanSex オブジェクトをデシリアライズするクラスです。
   */
  public static class Deserializer extends JsonDeserializer<HumanSex> {

    /**
     * JSON 解析時に性別コード(整数値)を HumanSex オブジェクトに変換します。
     */
    @Override
    public HumanSex deserialize(JsonParser parser, DeserializationContext context) throws IOException {
      return HumanSex.codeOf(parser.getIntValue());
    }
  }
}
package com.example;

import com.example.humansex.HumanSex;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

import java.util.ArrayList;
import java.util.List;

public class MyData {

  public List<Person> personList = new ArrayList<>();

  @Override
  public String toString() {
    StringBuilder buf = new StringBuilder();
    for (Person person : personList) {
      buf.append(person + System.lineSeparator());
    }
    return buf.toString();
  }

  public static class Person {

    public String name;

    // Jackson による JSON 生成・解析時に使うクラスをアノテーションで指定する
    @JsonSerialize(using = HumanSex.Serializer.class)
    @JsonDeserialize(using = HumanSex.Deserializer.class)
    public HumanSex sex;

    public Person() {
    }

    public Person(String name, HumanSex sex) {
      this.name = name;
      this.sex = sex;
    }

    @Override
    public String toString() {
      return "name=[" + name + "], sex=[" + sex.toString() + "]";
    }
  }
}
package com.example;

import com.example.humansex.HumanSex;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.io.StringWriter;

public class App {

  public static void main(String[] args) throws IOException {

    // データオブジェクトを生成
    MyData inputData = new MyData();
    inputData.personList.add(new MyData.Person("Peko",   HumanSex.NOT_KNOWN));
    inputData.personList.add(new MyData.Person("Anubis", HumanSex.MALE));
    inputData.personList.add(new MyData.Person("Isis",   HumanSex.FEMALE));
    inputData.personList.add(new MyData.Person("Robot",  HumanSex.NOT_APPLICABLE));

    // Jackson でデータオブジェクトから JSON 文字列を生成
    StringWriter out = new StringWriter();
    new ObjectMapper().writerWithDefaultPrettyPrinter().writeValue(out, inputData);
    String json = out.toString();

    // JSON 文字列を出力
    System.out.println("***** Mydata → JSON *****");
    System.out.println(json);

    // Jackson で JSON 文字列を解析してデータオブジェクトに変換
    MyData outputData = new ObjectMapper().readValue(json, MyData.class);

    // オブジェクトの文字列表現を出力
    System.out.println("***** JSON → Mydata *****");
    System.out.println(outputData);
  }
}

Gradle 設定ファイル

Gradle でビルドと実行をするための設定ファイル build.gradle を用意。

build.gradle 
plugins {
  id 'java'
  id 'application'
}

group 'org.example'
version '0.0.1'

sourceCompatibility = 11

repositories {
  mavenCentral()
}

dependencies {
  implementation 'com.fasterxml.jackson.core:jackson-databind:2.10.3'
}

application {
  mainClassName = 'com.example.App'
}

実行結果

***** Mydata → JSON *****
{
  "personList" : [ {
    "name" : "Peko",
    "sex" : 0
  }, {
    "name" : "Anubis",
    "sex" : 1
  }, {
    "name" : "Isis",
    "sex" : 2
  }, {
    "name" : "Robot",
    "sex" : 9
  } ]
}
***** JSON → Mydata *****
name=[Peko], sex=[NOT_KNOWN]
name=[Anubis], sex=[MALE]
name=[Isis], sex=[FEMALE]
name=[Robot], sex=[NOT_APPLICABLE]

参考資料

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1