⛄️
JacksonAnnotationsInsideでカスタムアノテーションを作る
今触っているライブラリがJacksonを使っているんですがObjectMapper
を中に抱え込んでいてまったくカスタマイズできなくて少し困っています。
そのためシリアライズ・デシリアライズをカスタマイズするときは次のようにフィールドにアノテーションを付与していたのですが、同じ型(この例ではLocalDateTime
)のフィールドがあるだけ同じようにアノテーションを付与する必要があって気が滅入っていました。
public record Tweet(
String name,
@JsonSerialize(using = ToStringSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
LocalDateTime timestamp) {
}
さすがに改善したいと思って調べてみるとJacksonAnnotationsInside
アノテーションを使うことでJsonSerialize
やJsonDeserialize
をまとめたカスタムアノテーションを作れることがわかりました。
試してみましょう。
アノテーションを作ってJsonSerialize
とJsonDeserialize
を付与します。
それからJacksonAnnotationsInside
も付与すれば作成完了です。
package com.example;
import java.lang.annotation.*;
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.annotation.*;
import com.fasterxml.jackson.databind.ser.std.*;
import com.fasterxml.jackson.datatype.jsr310.deser.*;
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = ToStringSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
public @interface LocalDateTimeJacksonAnnotations {
}
動作確認してみましょう。
作成したカスタムアノテーションをフィールドに付与します。
public record Tweet(
String content,
@LocalDateTimeJacksonAnnotations LocalDateTime timestamp) {
}
アノテーションがスッキリしました。
次のようなメインクラスを作って実行しましょう。
package com.example;
import java.time.*;
import com.fasterxml.jackson.databind.*;
public class App {
public static void main(String[] args) throws Exception {
Tweet tweet = new Tweet(
"なるほど四時じゃねーの",
LocalDateTime.parse("2022-01-02T04:00"));
String json = new ObjectMapper().writeValueAsString(tweet);
System.out.println(json);
}
}
出力は次の通りです。
{"content":"なるほど四時じゃねーの","timestamp":"2022-01-02T04:00"}
ちゃんとカスタムアノテーションが仕事してくれましたね。
以上です。
Discussion