Java7をやめてJava8で開発するようになり、java.util.Dateを使わなくなり、
Google gson で LocalDate / LocalDateTime をシリアライズ・デシリアライズするのに
簡単に書ける方法を探すのに苦労したのでその過程と結果です。
GsonBuilder の registerTypeAdapter で LocalDateのシリアライズ&デシリアライズ、
LocalDateTimeのシリアライズ&デシリアライズと、registerTypeAdapter の呼び出しを4回も書かなくてはならない。
new GsonBuilder().registerTypeAdapter(LocalDate.class, new JsonSerializer<LocalDate>(){
@Override
public JsonElement serialize(LocalDate date, Type type, JsonSerializationContext context){
return new JsonPrimitive(date.format(DateTimeFormatter.ofPattern("yyyy/MM/dd")));
}
}). /* このようなものを、毎回4つ書くのは辛い。。*/
そこで、以下のような Adapter を2つ用意する。
@FunctionalInterface
public interface LocalDateAdapter extends JsonSerializer<LocalDate>, JsonDeserializer<LocalDate> {
@Override
public default JsonElement serialize(LocalDate date, Type type, JsonSerializationContext context){
return new JsonPrimitive(date.format(getFormatter()));
}
@Override
public default LocalDate deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException{
return LocalDate.parse(json.getAsString(), getFormatter());
}
public static LocalDateAdapter create(LocalDateAdapter a){
return a;
}
public DateTimeFormatter getFormatter();
}
@FunctionalInterface
public interface LocalDateTimeAdapter extends JsonSerializer<LocalDateTime>, JsonDeserializer<LocalDateTime> {
@Override
public default JsonElement serialize(LocalDateTime datetime, Type type, JsonSerializationContext context){
return new JsonPrimitive(datetime.format(getFormatter()));
}
@Override
public default LocalDateTime deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException{
return LocalDateTime.parse(json.getAsString(), getFormatter());
}
public static LocalDateTimeAdapter create(LocalDateTimeAdapter a){
return a;
}
public DateTimeFormatter getFormatter();
}
========================
こうすると。。。
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation() .registerTypeAdapter(LocalDate.class, LocalDateAdapter.create(()->DateTimeFormatter.ofPattern("yyyy/MM/dd"))) .registerTypeAdapter(LocalDateTime.class, LocalDateTimeAdapter.create(()->DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss.SSS"))) .create();
と日付時刻のフォーマッタを指定する呼び出しとして書くことができる。