[英]Jackson , java.time , ISO 8601 , serialize without milliseconds
我正在使用Jackson 2.8並且需要與ISO 8601時間戳內不允許毫秒的API進行通信。
預期格式為: "2016-12-24T00:00:00Z"
我正在使用Jackson的JavaTimeModule, WRITE_DATES_AS_TIMESTAMPS
設置為false
。
但這將打印毫秒。
所以我嘗試使用沒有改變任何東西的objectMapper.setDateFormat
。
我目前的解決方法是:
ObjectMapper om = new ObjectMapper();
DateTimeFormatter dtf = new DateTimeFormatterBuilder()
.appendInstant(0)
.toFormatter();
JavaTimeModule jtm = new JavaTimeModule();
jtm.addSerializer(Instant.class, new JsonSerializer<Instant>() {
@Override
public void serialize(Instant value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
gen.writeString(dtf.format(value));
}
});
om.registerModule(jtm);
我正在覆蓋Instant.class
的默認序列化Instant.class
。
有沒有什么好辦法使用一些配置參數來解決這個問題?
只需在Instant
屬性上方添加日期格式的@JsonFormat
注釋即可。 這很容易。
如果你有一個帶有JavaTimeModule
的ObjectMapper,就像下一個:
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
如果你有一個具有Instant
屬性的類,你應該添加@JsonFormat
注釋並放置沒有毫秒的日期模式。 這就像下一個:
public static class TestDate {
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss", timezone = "UTC")
Instant instant;
//getters & setters
}
因此,如果您將對象序列化為Json,它可以完美地運行:
String json = mapper.writeValueAsString(testDate);
System.out.println(json);
產量
{“instant”:“2016-11-10 06:03:06”}
您可以使用Jackson2ObjectMapperBuilder
來構建它。
您只需要添加所需的dateFormat。 這將是下一個:
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
ObjectMapper mapper = Jackson2ObjectMapperBuilder
.json()
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.modules(new JavaTimeModule())
.dateFormat(dateFormat)
.build();
這是一個可以全局設置的替代方法,但是需要您使用ZonedDateTime
和即時格式化程序,因為我們無法設置隨Java Time Module提供的Instant
Serializer的格式。
您不會看到使用分區日期時間為即時的任何副作用,因為傑克遜分別序列化區域ID並默認禁用。 從技術上講,這類似於將格式化程序應用於Instant
。
以這種方式使用時, ZonedDateTime
序列化程序將序列化委派給InstantBaseSerializer
並使用指定的自定義格式。
@RunWith(JUnit4.class)
public class InstantNoMillisTest {
private ObjectMapper objectMapper;
@Before
public void init() {
JavaTimeModule module = new JavaTimeModule();
ZonedDateTimeSerializer zonedDateTimeSerializer = new ZonedDateTimeSerializer(new DateTimeFormatterBuilder().appendInstant(0).toFormatter());
module.addSerializer(ZonedDateTime.class, zonedDateTimeSerializer);
module.addDeserializer(ZonedDateTime.class, InstantDeserializer.ZONED_DATE_TIME);
objectMapper = Jackson2ObjectMapperBuilder.json()
.modules(module)
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.build();
}
@Test
public void serialize() throws IOException {
ZonedDateTime zonedDateTime = ZonedDateTime.now();
String noMillis = objectMapper.writeValueAsString(zonedDateTime);
System.out.print(noMillis);
}
@Test
public void deserialize() throws IOException {
String dateTime = "\"2017-10-26T12:54:59Z\"";
ZonedDateTime noMillis = objectMapper.readValue(dateTime, ZonedDateTime.class);
System.out.print(noMillis);
}
}
這里有一些格式化Instant
字段的Kotlin代碼,因此它們不包含毫秒,您可以使用自定義日期格式化程序
ObjectMapper().apply {
val javaTimeModule = JavaTimeModule()
javaTimeModule.addSerializer(Instant::class.java, Iso8601WithoutMillisInstantSerializer())
registerModule(javaTimeModule)
disable(WRITE_DATES_AS_TIMESTAMPS)
}
private class Iso8601WithoutMillisInstantSerializer
: InstantSerializer(InstantSerializer.INSTANCE, false, DateTimeFormatterBuilder().appendInstant(0).toFormatter())
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.