LoginSignup
15
16

More than 5 years have passed since last update.

JacksonつかってJavaオブジェクトをJSONに変換する際、enum型を数値で出力する

Posted at

JacksonっていうのはJavaオブジェクトをJSON文字列に変換してくれる便利なアレです。
Jackson自体に関してはいろいろ記事があるのでそれを参考にしてください。

enumが文字列として出力されてしまうのダルい

今回の問題点は、以下です。

Javaオブジェクトにenum型が含まれる場合、値が数値ではなくキーの文字列として出力されてしまう

例えば以下。

// enum型を定義
public enum DayOfWeek {
    Sunday,
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday
}

// オブジェクトのクラスを定義
public class PeriodicTodo implements Serializable {
    private String todo;
    private DayOfWeek day;

    public String getTodo() { return todo; }
    public void setTodo(String todo) { this.todo = todo; }

    public DayOfWeek getDay() { return day; }
    public void setDay(DayOfWeek day) { this.day = day; }
}

あとはこれを使ってJavaオブジェクトをJSONにシリアライズ

// インスタンス生成
PeriodicTodo todo = new PeriodicTodo();
todo.setTodo('do something');
todo.setDay(DayOfWeek.Monday);


// シリアライズ
ObjectMapper mapper = new ObjectMapper();
String serialized = mapper.writeValueAsString(todo);
System.out.println(serialized);

// ホントはMondayを数値で出力したかった!!
// 結果 ==> { "todo":"do something","day":"Monday" }

enumでも独自にシリアライズできるようにする

dayは数値で出力したいっていう場合には独自のシリアライザを作りましょう。

以下のようにenumにJsonSerializableを実装し、Jsonシリアライズ可能にしてやります。

// enum型をシリアライズ可能に
public enum DayOfWeek implements JsonSerializable {
    Sunday,
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday;

    @Override
    public void serialize(JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
        jgen.writeNumber(ordinal());
    }

    @Override
    public void serializeWithType(JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer)  throws IOException, JsonProcessingException  {
        jgen.writeNumber(ordinal());
    }
}

あとはさっきと同じことすれば見事数字で出力されます

// インスタンス生成
PeriodicTodo todo = new PeriodicTodo();
todo.setTodo('do something');
todo.setDay(DayOfWeek.Monday);


// シリアライズ
ObjectMapper mapper = new ObjectMapper();
String serialized = mapper.writeValueAsString(todo);
System.out.println(serialized);

// 結果 ==> { "todo":"do something","day":1 }

enumでもimplementsできるなんて地味に知らなかった。

15
16
2

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
15
16