在处理时间字段的序列化时,如果不做特殊的操作,时间字段一般会序列化成你想象不到的数据类型。
如下,我们定义了一个实体,包含了一个Date的字段
@AllArgsConstructor(staticName = "of")
@NoArgsConstructor
class DateEntity{
@Getter
private Date time;
}
如果我们什么都不处理,直接的序列化,代码如下
@Test
public void JsonFormatTest() throws Exception{
CombineJacksonAnnotation.DateEntity dateEntity = CombineJacksonAnnotation.DateEntity.of(new Date());
System.out.println(om.writeValueAsString(dateEntity));
}
结果如下
{
"time" : 1606734419777
}
一般来说我们希望返回的pattern是 2015-12-12这样的模式,那么@JsonFormat就派上用场了,我们在属性上面打上如下的标签
@AllArgsConstructor(staticName = "of")
@NoArgsConstructor
class DateEntity{
@Getter
@Setter /
@JsonFormat(shape = JsonFormat.Shape.STRING,pattern = "yyyy-MM-dd HH:mm:ss")
private Date time;
}
我们接着序列化,返回如下的结果
{
"time" : "2020-11-30 11:10:42"
}
格式对了,但是与当前时间差了8个小时,我们再修改成如下
@JsonFormat(shape = JsonFormat.Shape.STRING,pattern = "yyyy-MM-dd HH:mm:ss", locale = "zh_CN",timezone = "Asia/Shanghai")
返回的时间就对了,现在对@JsonFormat注解里面的属性做下介绍
1 shape
表明字段序列化后的类型,如 STRING 表示序列化成string的格式,而NUMBER表明序列化成数字类型。
2 pattern 这个不过多的介绍,可以自由的设定序列化的样式
3 locale 这个在序列化的时候指定国际化
4 timezone 指定时区 不指定的话默认是GMT,我们这里设置成GMT+8或是Asia/Shanghai都可以
5 lenient 反序列化时,是否激活严格校验模式。一般保持默认即可。
6 with 可以enable JsonFormat.Feature的特征,会覆盖全局配置
7 without 含义与6相反。
我们可以试验下with属性,我们将实体修改成如下的样子
@AllArgsConstructor(staticName = "of")
@NoArgsConstructor
class DateEntity{
@Getter
@Setter
@JsonFormat(shape = JsonFormat.Shape.STRING,pattern = "yyyy-MM-dd HH:mm:ss",locale = "zh_CN",timezone = "Asia/Shanghai")
private List<Date> time;
}
如果我们执行如下的UT,会报错
@Test
public void JsonFormatTest() throws Exception{
CombineJacksonAnnotation.DateEntity dateEntity = om.readValue("{\n" +
" \"time\" : \"2020-11-30 09:05:01\"\n" +
"}",CombineJacksonAnnotation.DateEntity.class);
}
如下
因为我们的time是一个list列表,但是反序列话的时候是一个单独的值,我们修改成如下的样式
@JsonFormat(shape = JsonFormat.Shape.STRING,pattern = "yyyy-MM-dd HH:mm:ss", with = {JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY},locale = "zh_CN",timezone = "Asia/Shanghai")
设置完之后,再反序列化,就会成功了。等于说@JsonFormat不只是用于Date类型的反序列化,而是一个通用的注解,如果用好了,会非常的方便