Posted at

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

More than 3 years have passed since last update.

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できるなんて地味に知らなかった。