_Spring Boot 2.0.0.M6
_、_Spring Framework 5.0.1.RELEASE
_、および_Jackson 2.9.2
_を使用するプロジェクトでJacksonを使用したJSONシリアル化に関連するいくつかの質問があります。
_application.properties
_で次のジャクソン関連の設定を構成しました。
_spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false
_
シリアル化は主に必要に応じて機能します。それでも、ジャクソンが_000
_の場合、ミリ秒をカットオフしているように見えることに気づきました。
テスト1:ミリ秒を_000
_:に設定してインスタントをシリアル化する
Instant.parse("2017-09-14T04:28:48.000Z")
を使用してインスタントフィールドを初期化します"2017-09-14T04:28:48Z"
_になりますテスト2:ミリ秒を_000
_以外の値に設定してインスタントをシリアル化:
Instant.parse("2017-09-14T04:28:48.100Z")
を使用してインスタントフィールドを初期化します"2017-09-14T04:28:48.100Z"
_になります質問:
000
_のシリアル化を強制するためにできることはありますか?これにはジャクソンの問題が開いているようです ここ *。そのリンクには2つの回避策が含まれています
回避策1
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
SimpleModule module = new SimpleModule();
module.addSerializer(ZonedDateTime.class, new JsonSerializer<ZonedDateTime>() {
@Override
public void serialize(ZonedDateTime zonedDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
jsonGenerator.writeString(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZZZ").format(zonedDateTime));
}
});
objectMapper.registerModule(module);
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
回避策2
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(ZonedDateTime.class,
new ZonedDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX")));
ObjectMapper mapper = new ObjectMapper().registerModule(javaTimeModule);
* FasterXML/jackson-datatype-jsr310が非推奨になり、 jackson-modules-Java8 に移動されたため、リンクは無効になっています。 https://github.com/FasterXML/jackson-modules-Java8/issues/76 を参照してください
私はこのアプローチを使用して解決します:
ObjectMapper objectMapper = new ObjectMapper();
JavaTimeModule module = new JavaTimeModule();
module.addSerializer(Instant.class, new InstantSerializerWithMilliSecondPrecision());
objectMapper.registerModule(module);
そしてInstantSerializerWithMilliSecondPrecisionのために私はこれを使用しました:
public class InstantSerializerWithMilliSecondPrecision extends InstantSerializer {
public InstantSerializerWithMilliSecondPrecision() {
super(InstantSerializer.INSTANCE, false, new DateTimeFormatterBuilder().appendInstant(3).toFormatter());
}
}
現在、インスタントシリアル化には常にミリ秒が含まれています。例:2019-09-27T02:59:59.000Z
ショーンキャロルが言及した2つの回避策のどれも私にはうまくいきません。結局、Instant用に独自のシリアライザーを作成することになります。
_final ObjectMapper mapper = new ObjectMapper();
final JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(Instant.class, new KeepMillisecondInstantSerializer());
mapper.registerModule(javaTimeModule);
public class KeepMillisecondInstantSerializer extends JsonSerializer<Instant> {
private final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX")
.withZone(ZoneId.of("UTC"));
@Override
public void serialize(final Instant instant, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider) throws IOException {
final String serializedInstant = dateTimeFormatter.format(instant);
jsonGenerator.writeString(serializedInstant);
}
}
_
Jackson Instant.toString()
メソッドを使用してInstantオブジェクトをシリアル化する デフォルトで。私はまた StackOverflowのInstant.toString()
メソッドに関するいくつかの議論 を見つけます。