Jackson是一个Java的用来处理JSON格式数据的类库,性能非常好。在项目开发中,使用Jackson库的@JsonSerialize注解实现日期的自定义格式的序列化,这里做一个记录。
一、需求背景
对于一个Model层对象的Date字段,在序列化为JSON数据时,可以使用Jakson库的@JsonFormat注解来定义格式,比如:
@Data public class TestClass { @JsonFormat(pattern="yyyy-MM-dd",timezone = "GMT+8") private Date testTime; }
|
在项目的实际开发过程中,这个日期可能不是Date,而是其他格式,比如Instant,此时再使用@JsonFormat注解就会报错。此时可以通过继承StdSerializer抽象类和@JsonSerialize注解来实现自定义格式的序列化。
二、源代码
1. Instant序列化类InstantSerializer.java
public class InstantSerializer extends StdSerializer<Instant> {
private static DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
public InstantSerializer() { this(null); }
public InstantSerializer(Class<Instant> t) { super(t); }
@Override public void serialize(Instant instant, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException { if (instant == null) { return; } String jsonValue = format.format(instant.atZone(ZoneId.of("Asia/Shanghai"))); jsonGenerator.writeString(jsonValue); } }
|
InstantSerializer继承了StdSerializer抽象类,将Instant序列化为”yyyy-MM-dd HH:mm:ss”的日期格式。
2. String序列化类UTCDaySerializer.java
public class UTCDaySerializer extends StdSerializer<String> {
public UTCDaySerializer() { this(null); }
public UTCDaySerializer(Class<String> t) { super(t); }
@Override public void serialize(String timeString, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException { if (timeString == null) { return; } int index = timeString.indexOf("T"); String jsonValue = timeString.substring(0, index); jsonGenerator.writeString(jsonValue); } }
|
UTCDaySerializer也继承了StdSerializer抽象类,将UTC格式的String日期,即”yyyy-MM-dd’T’HH:mm:ss’Z’”截取前半段,即”yyyy-MM-dd”的日期格式。
3. LogStatusDTO.java
@Data @Builder public class LogStatusDTO { @JsonSerialize(using = InstantSerializer.class) private Instant timestamp;
private String content; }
|
使用@JsonSerialize注解和InstantSerializer来序列化Instant类型的timestamp字段。
4. ServiceLogNumPerDayDTO.java
@Data @Measurement(name = "log") public class ServiceLogNumPerDayDTO { @Column(name = "time") @JsonSerialize(using = UTCDaySerializer.class) String date;
@Column(name = "count_content") Integer count; }
|
使用@JsonSerialize注解和UTCDaySerializer来序列化String类型的date字段。