😎
long値のミリ秒をLocalDateTimeにデシリアライズする
概要
RestTemplate
でAPIをコールして得られる返戻値は時刻をミリ秒で扱ってるが、
プログラム中ではLocalDateTime
で扱いたい場合に、デシリアライズのタイミングで変換させる実装
前提
デシリアライズしたいjson
{
"eventTime":1676101633075
}
Event.class
public class Event {
LocalDateTime eventTime;
}
javaでjson文字列をデシリアライズする際、jackson
のobjectMapper
を使うことが多いと思われますが、上記のままだとデシリアライズがうまくいきません。
Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling
at [Source: (String)"{ "eventTime" : 1676101633075 }"; line: 1, column: 17] (through reference chain: org.example.Event["eventTime"])
デシリアライザーを実装する
StdDeserializerを継承したカスタムデシリアライザーを実装し、eventTime
フィールドのデシリアライザーとして設定することで、ミリ秒の時刻をそのままLocalDateTimeとして、デシリアライズすることができます。
LocalDateTimeDeserializer.class
public class LocalDateTimeDeserializer extends StdDeserializer<LocalDateTime> {
protected LocalDateTimeDeserializer(){
super (LocalDateTime.class);
}
@Override
public LocalDateTime deserialize(JsonParser p , DeserializationContext ctxt) throws IOException{
final long epochmillis = p.readValueAs(Long.class);
return LocalDateTime.ofInstant(Instant.ofEpochMilli(epochmillis), ZoneId.systemDefault());
}
}
Event.class
public class Event {
// 実装したカスタムデシリアライザーを設定
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
LocalDateTime eventTime;
}
Main.class
public class Main {
public static void main(String[] args) throws Exception{
String jsonEvent = "{ \"eventTime\" : 1676101633075 }";
Event event = new ObjectMapper().readValue(jsonEvent, Event.class);
System.out.println("eventTime is " + event.getEventTime());
// eventTime is 2023-02-11T16:47:13.075
}
}
↑例外が発生せず、ミリ秒・long型の時刻をLocalDateTimeにデシリアライズすることができました。
Discussion