读者盆友们,晚上好。
这里分享下日常开发经常遇到的一个问题:时间DateTime序列化和反序列化的问题:如果不处理,那么序列化和反序列化就有问题。
import org.joda.time.DateTime;
class CreateCouponCommand{
private DateTime validFrom;
private DateTime validUntil;
//省略get set方法
}
这个类在序列化或者反序列化的时候会有什么问题嘛?一般是不会有的;如果存储数据库的时候,发现是这样的格式,那就有问题了:
validFrom": {
"afterNow": false,
"beforeNow": true,
"centuryOfEra": 20,
"chronology": {
"zone": {
"fixed": true,
"iD": "UTC"
}
},
"dayOfMonth": 7,
"dayOfWeek": 2,
"dayOfYear": 98,
"equalNow": false,
"era": 1,
"hourOfDay": 3,
"millis": 1586231107919,
"millisOfDay": 13507919,
"millisOfSecond": 919,
"minuteOfDay": 225,
"minuteOfHour": 45,
"monthOfYear": 4,
"secondOfDay": 13507,
"secondOfMinute": 7,
"weekOfWeekyear": 15,
"weekyear": 2020,
"year": 2020,
"yearOfCentury": 20,
"yearOfEra": 2020,
"zone": {
"$ref": "$[0].ToFvarom.chronology.zone"
}
},
这当然不是我们想要的,那么问题出在哪呢?
其实,上面的CreateCouponCommand是简化的一个版本,实际代码这个vaildUntil字段是嵌套在一个
List中的一个属性,我们是用JsonUtils.ObjectToString(),底层用fastjson来序列化这个List对象的,也就是说这个List在数据库对应一个字段:business_cmd
这个字段理想情况持久化后应该是这样的:
[
{
"validFrom":"2020-04-10T11:32:04.000Z",
"validUntil":"2020-04-10T11:32:04.000Z"
},
{
"validFrom":"2020-04-10T11:32:04.000Z",
"validUntil":"2020-04-10T11:32:04.000Z"
},
]
时间应该是UTC时间字符串才对,然而,实际存储下来后是这样的:
[
{
"validFrom":{
"afterNow": false,
"beforeNow": true,
"centuryOfEra": 20,
"chronology": {
"zone": {
"fixed": true,
"iD": "UTC"
}
},
"dayOfMonth": 7,
"dayOfWeek": 2,
"dayOfYear": 98,
"equalNow": false,
"era": 1,
"hourOfDay": 3,
"millis": 1586231107919,
"millisOfDay": 13507919,
"millisOfSecond": 919,
"minuteOfDay": 225,
"minuteOfHour": 45,
"monthOfYear": 4,
"secondOfDay": 13507,
"secondOfMinute": 7,
"weekOfWeekyear": 15,
"weekyear": 2020,
"year": 2020,
"yearOfCentury": 20,
"yearOfEra": 2020,
"zone": {
"$ref": "$[0].ToFvarom.chronology.zone"
}
},
"validUntil":"同上"
},
{
"validFrom":"同上",
"validUntil":"同上"
},
]
问题出在哪里?
出在fastjson不能自动序列化和反序列化日期,怎么办?那就自定义序列化和反序列化,而不是交给fastjson自动去做这些事。看下下注解方式的解决方案:
@ApiModelProperty(value = "过期时间")
@JSONField(name = "validUntil", deserializeUsing = DateTimeJsonDeserializer.class, serializeUsing = DateTimeJsonSerializer.class)
private DateTime validUntil;
这个@JSONField注解还是fastjson的,不过里面的2个:反序列化、序列化是自己重写的,具体代码就不展示了,网上解决思路很多,每个公司也可能都有自己的处理方式。
首先看到日期入库格式不对,立刻就想到日期序列化问题,那就要看本来用的什么来序列化的,我们用的是fastjson,这个处理日期有问题,怎么办?那就自定义序列化过程。
好了,下期再会!