使用 Jackson 将 Java8 LocalDateTime 序列化为 UTC 时间戳
Serialize Java8 LocalDateTime to UTC Timestamp using Jackson
我刚刚根据新的(ish)java 8 时间包将我的许多日期转换为 LocalDateTime。到目前为止,在我开始尝试序列化和反序列化之前,我一直很喜欢这种转换。
如何配置 Jackson 以支持它们?:
LocalDateTime --serialize--> UTC 时间戳--反序列化--> LocalDateTime?
这里有很多关于转换为格式化字符串的 material,但我似乎找不到针对 utc 时间戳的现成解决方案。
您可以为 LocalDateTime
自定义序列化器和反序列化器,例如:
CustomLocalDateTimeSerializer
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneId;
public class CustomLocalDateTimeSerializer extends StdSerializer<LocalDateTime> {
protected CustomLocalDateTimeSerializer(Class<LocalDateTime> t) {
super(t);
}
protected CustomLocalDateTimeSerializer() {
this(null);
}
@Override
public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider sp)
throws IOException {
Long epoch = value.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond();
gen.writeString(epoch.toString());
}
}
CustomLocalDateTimeDesSerializer:
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import java.io.IOException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
class CustomLocalDateTimeDesSerializer extends StdDeserializer<LocalDateTime> {
protected CustomLocalDateTimeDesSerializer() {
this(null);
}
protected CustomLocalDateTimeDesSerializer(Class<LocalDateTime> t) {
super(t);
}
@Override
public LocalDateTime deserialize(JsonParser jsonparser, DeserializationContext context)
throws IOException {
Long timestamp = Long.parseLong(jsonparser.getText());
return LocalDateTime.ofInstant(Instant.ofEpochSecond(timestamp), ZoneId.systemDefault());
}
}
并使用它们:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.time.LocalDateTime;
public class RestObject {
private LocalDateTime timestamp = LocalDateTime.now();
@JsonSerialize(using = CustomLocalDateTimeSerializer.class)
@JsonDeserialize(using = CustomLocalDateTimeDesSerializer.class)
public LocalDateTime getTimestamp() {
return timestamp;
}
public static void main(String[] args) throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
// {"timestamp":"1549026058"}
System.out.println(objectMapper.writeValueAsString(new RestObject()));
}
}
您可以利用 the JavaTimeModule
:
而不是手动重写所有内容
ObjectMapper om = new ObjectMapper();
om.registerModule(new JavaTimeModule());
om.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true);
以下是简单高效的方法:
@JsonFormat(shape= JsonFormat.Shape.STRING, pattern="EEE MMM dd HH:mm:ss Z yyyy")
@JsonProperty("created_at")
ZonedDateTime created_at;
这是一个问题的引用:,所以这可能是一个重复的问题
以下解决方案解决了 serialize/deserialise LocalDateTime
与时间戳相关的任务,至少与 spring-boot v1.5 相关,并且还包括未采用的下一个点考虑到@xingbin 的 :
- 如果需要具有与
java.util.Date
相同的行为,则必须使用 toInstant().toEpochMilli()
而不是 toInstant().getEpochSecond()
- 检查
null
要反序列化的值
- 和可选点:为 Jackson
ObjectMapper
指定此 serialization/deserialization 配置
时间戳序列化器class:
public class LocalDateTimeSerializer extends StdSerializer<LocalDateTime> {
private static final ZoneId DEFAULT_ZONE_ID = ZoneId.of("UTC");
public LocalDateTimeSerializer() {
super(LocalDateTime.class);
}
@Override
public void serialize(final LocalDateTime value,
final JsonGenerator generator,
final SerializerProvider provider) throws IOException {
if (value != null) {
final long mills = value.atZone(DEFAULT_ZONE_ID).toInstant().toEpochMilli();
generator.writeNumber(mills);
} else {
generator.writeNull();
}
}
}
时间戳解串器class:
public class LocalDateTimeDeserializer extends StdDeserializer<LocalDateTime> {
private static final ZoneId DEFAULT_ZONE_ID = ZoneId.of("UTC");
public LocalDateTimeDeserializer() {
super(LocalDateTime.class);
}
@Override
public LocalDateTime deserialize(final JsonParser parser,
final DeserializationContext context) throws IOException {
final long value = parser.getValueAsLong();
return LocalDateTime.ofInstant(Instant.ofEpochMilli(value), DEFAULT_ZONE_ID);
}
}
对象映射器配置:
@Configuration
public class ObjectMapperConfiguration {
@Bean
public ObjectMapper objectMapper() {
final ObjectMapper objectMapper = new ObjectMapper();
final SimpleModule module = new SimpleModule();
module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());
objectMapper.registerModule(module);
return objectMapper;
}
}
我刚刚根据新的(ish)java 8 时间包将我的许多日期转换为 LocalDateTime。到目前为止,在我开始尝试序列化和反序列化之前,我一直很喜欢这种转换。
如何配置 Jackson 以支持它们?:
LocalDateTime --serialize--> UTC 时间戳--反序列化--> LocalDateTime?
这里有很多关于转换为格式化字符串的 material,但我似乎找不到针对 utc 时间戳的现成解决方案。
您可以为 LocalDateTime
自定义序列化器和反序列化器,例如:
CustomLocalDateTimeSerializer
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneId;
public class CustomLocalDateTimeSerializer extends StdSerializer<LocalDateTime> {
protected CustomLocalDateTimeSerializer(Class<LocalDateTime> t) {
super(t);
}
protected CustomLocalDateTimeSerializer() {
this(null);
}
@Override
public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider sp)
throws IOException {
Long epoch = value.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond();
gen.writeString(epoch.toString());
}
}
CustomLocalDateTimeDesSerializer:
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import java.io.IOException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
class CustomLocalDateTimeDesSerializer extends StdDeserializer<LocalDateTime> {
protected CustomLocalDateTimeDesSerializer() {
this(null);
}
protected CustomLocalDateTimeDesSerializer(Class<LocalDateTime> t) {
super(t);
}
@Override
public LocalDateTime deserialize(JsonParser jsonparser, DeserializationContext context)
throws IOException {
Long timestamp = Long.parseLong(jsonparser.getText());
return LocalDateTime.ofInstant(Instant.ofEpochSecond(timestamp), ZoneId.systemDefault());
}
}
并使用它们:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.time.LocalDateTime;
public class RestObject {
private LocalDateTime timestamp = LocalDateTime.now();
@JsonSerialize(using = CustomLocalDateTimeSerializer.class)
@JsonDeserialize(using = CustomLocalDateTimeDesSerializer.class)
public LocalDateTime getTimestamp() {
return timestamp;
}
public static void main(String[] args) throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
// {"timestamp":"1549026058"}
System.out.println(objectMapper.writeValueAsString(new RestObject()));
}
}
您可以利用 the JavaTimeModule
:
ObjectMapper om = new ObjectMapper();
om.registerModule(new JavaTimeModule());
om.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true);
以下是简单高效的方法:
@JsonFormat(shape= JsonFormat.Shape.STRING, pattern="EEE MMM dd HH:mm:ss Z yyyy")
@JsonProperty("created_at")
ZonedDateTime created_at;
这是一个问题的引用:
以下解决方案解决了 serialize/deserialise LocalDateTime
与时间戳相关的任务,至少与 spring-boot v1.5 相关,并且还包括未采用的下一个点考虑到@xingbin 的
- 如果需要具有与
java.util.Date
相同的行为,则必须使用toInstant().toEpochMilli()
而不是toInstant().getEpochSecond()
- 检查
null
要反序列化的值 - 和可选点:为 Jackson
ObjectMapper
指定此 serialization/deserialization 配置
时间戳序列化器class:
public class LocalDateTimeSerializer extends StdSerializer<LocalDateTime> {
private static final ZoneId DEFAULT_ZONE_ID = ZoneId.of("UTC");
public LocalDateTimeSerializer() {
super(LocalDateTime.class);
}
@Override
public void serialize(final LocalDateTime value,
final JsonGenerator generator,
final SerializerProvider provider) throws IOException {
if (value != null) {
final long mills = value.atZone(DEFAULT_ZONE_ID).toInstant().toEpochMilli();
generator.writeNumber(mills);
} else {
generator.writeNull();
}
}
}
时间戳解串器class:
public class LocalDateTimeDeserializer extends StdDeserializer<LocalDateTime> {
private static final ZoneId DEFAULT_ZONE_ID = ZoneId.of("UTC");
public LocalDateTimeDeserializer() {
super(LocalDateTime.class);
}
@Override
public LocalDateTime deserialize(final JsonParser parser,
final DeserializationContext context) throws IOException {
final long value = parser.getValueAsLong();
return LocalDateTime.ofInstant(Instant.ofEpochMilli(value), DEFAULT_ZONE_ID);
}
}
对象映射器配置:
@Configuration
public class ObjectMapperConfiguration {
@Bean
public ObjectMapper objectMapper() {
final ObjectMapper objectMapper = new ObjectMapper();
final SimpleModule module = new SimpleModule();
module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());
objectMapper.registerModule(module);
return objectMapper;
}
}