在项目中将fastjson升级为fastjson2后,我们遇到了一些与fastjson不完全兼容的问题。本文将探讨下fastjson2的时间序列化和反序列化的简单使用。
时间序列化
在fastjson2
中,若要将Java对象中的时间属性序列化为JSON字符串,需使用@JSONField
注解指定时间格式,或在序列化时通过方法参数传入格式。
// 使用注解指定格式
@JSONField(format = "yyyy-MM-dd")
private Date dateField;
// 或者在序列化时通过方法参数传入格式
String jsonString = JSON.toJSONString(bean, "yyyy-MM-dd");
时间反序列化
与序列化类似,将日期字符串反序列化为Java对象中的时间属性时,同样可通过@JSONField
注解或方法参数指定时间格式。
// 使用注解指定格式
@JSONField(format = "yyyy-MM-dd")
private Date dateField;
// 或者在反序列化时通过方法参数传入格式
Bean bean = JSON.parseObject(jsonString, Bean.class, "yyyy-MM-dd");
fastjson2
的默认时间格式
在序列化时间时,默认格式为yyyy-MM-dd HH:mm:ss.SSS
,这与Jackson和fastjson v1的默认13位毫秒值时间戳格式有所不同。
fastjson2
支持配置全局默认时间格式,
- 序列化默认时间格式可通过
JSON.configWriterDateFormat(format)
设置。 - 反序列化默认时间格式可通过
JSON.configReaderDateFormat(format)
设置。
其中format
值可以参考下文中的 format说明。
fastjson2的隐藏功能
默认兼容Jackson
、Gson
以及fastjson
的注解,新一些的版本支持通过配置关闭Jackson
和Gson
的注解兼容,fastjson不支持关闭(也说不定后面会支持、毕竟Jackson
和Gson
也是后面的版本才添加的支持配置关闭兼容)。
翻了下
fastjson2
的源码,jackson的30多个注解基本都支持了,但是这个在官方文档中却没有任何说明。
格式化优先级
在fastjson2中,时间格式的优先级为:JSONField.format > 方法参数format > 全局配置
。
format
说明
- iso8601:遵循ISO 8601标准格式,如
2024-12-27T11:22:48.404+08:00
。 - millis:13位时间戳,。
- unixtime:10位时间戳,。
- 其他格式:遵循Java的
SimpleDateFormat
标准,如yyyy-MM-dd HH:mm:ss
。
时间格式化组件
以下列出了Java日期和时间格式化中常用的组件及其含义:
特别注意,这里是区分大小写字母的,比如
y
和Y
在日期格式化中有不同含义,y
表示当前日期归属年份,而Y
表示当前周归属的年份,这在年末时可能导致日期显示错误。
组件 | 描述 | 格式 | 示例 |
---|---|---|---|
G | 年代指示符 | 文本 | AD (公元) |
y | 年份 | 年份 | 1996 ;96 |
Y | 周年份(基于周计算) | 年份 | 2009 ;09 |
M | 年中的月份(上下文敏感) | 月份 | July ;Jul ;07 |
L | 年中的月份(独立形式) | 月份 | July ;Jul ;07 |
w | 年中的周数 | 数字 | 27 |
W | 月中的周数 | 数字 | 2 |
D | 年中的天数 | 数字 | 189 |
d | 月中的天数 | 数字 | 10 |
F | 月中的星期天数 | 数字 | 2 |
E | 星期中的天数名称 | 文本 | Tuesday ;Tue |
u | 星期中的天数编号(1=星期一,…,7=星期日) | 数字 | 1 |
a | 上午/下午标记 | 文本 | PM |
H | 一天中的小时(0-23) | 数字 | 0 |
k | 一天中的小时(1-24) | 数字 | 24 |
K | 上/下午中的小时(0-11) | 数字 | 0 |
h | 上/下午中的小时(1-12) | 数字 | 12 |
m | 小时中的分钟 | 数字 | 30 |
s | 分钟中的秒 | 数字 | 55 |
S | 毫秒 | 数字 | 978 |
z | 时区 | 一般时区 | Pacific Standard Time ;PST ;GMT-08:00 |
Z | 时区 | RFC 822时区 | -0800 |
X | 时区 | ISO 8601时区 | -08 ;-0800 ;-08:00 |
时间格式化组件说明
代码示例
以下是使用fastjson2进行时间序列化和反序列化的示例代码。
代码中用到的fastjson版本是 1.2.83,fastjson2版本是2.0.53。
fastjson2 Maven依赖:
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.53</version>
</dependency>
fastjson Maven依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
测试类
public class DemoTest {
public static void main(String[] args) {
//序列化
testToJSONString();
//fastjson 序列化 和2进行一个对比
testFastJson1ToJSON();
//解析为java对象
testParseObject();
}
private static void testToJSONString() {
Date now = new Date();
Bean bean = new Bean();
bean.setUnixTimeDate(now);
bean.setIso8601Date(now);
bean.setMillisDate(now);
bean.setDefaultDate(now);
bean.setDataFormatDate(now);
System.out.println("fastjson2 全局配置format前序列化结果");
System.out.println(JSON.toJSONString(bean));
String format = "millis";
JSON.configWriterDateFormat(format);
System.out.println("fastjson2 全局配置format后序列化结果");
System.out.println(JSON.toJSONString(bean));
System.out.println("fastjson2 方法传入format序列化结果");
System.out.println(JSON.toJSONString(bean,"yyyyMMdd"));
}
private static void testFastJson1ToJSON() {
Date now = new Date();
Bean1 bean1 = new Bean1();
bean1.setUnixTimeDate(now);
bean1.setIso8601Date(now);
bean1.setMillisDate(now);
bean1.setDefaultDate(now);
System.out.println("fastjson 序列化结果");
System.out.println(com.alibaba.fastjson.JSON.toJSONString(bean1));
}
private static void testParseObject() {
String json = "{\n" +
" \"dataFormatDate\": \"2024-12-27 10:50:31\",\n" +
" \"defaultDate\": \"2024-12-27 10:50:31.555\",\n" +
" \"iso8601Date\": \"2024-12-27T10:50:31.555+08:00\",\n" +
" \"millisDate\": 1735267831555,\n" +
" \"unixTimeDate\": 1735267831\n" +
"}";
Bean yyyyMMdd = JSON.parseObject(json, Bean.class);
System.out.println("fastjson2 反序列化结果: " + yyyyMMdd.toString());
}
}
fastjson2的测试bean类
public class Bean {
@JSONField(format = "millis")
private Date millisDate;
@JSONField(format = "unixtime")
private Date unixTimeDate;
@JSONField(format = "iso8601")
private Date iso8601Date;
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date dataFormatDate;
private Date defaultDate;
public Date getDataFormatDate() {
return dataFormatDate;
}
public void setDataFormatDate(Date dataFormatDate) {
this.dataFormatDate = dataFormatDate;
}
public Date getMillisDate() {
return millisDate;
}
public void setMillisDate(Date millisDate) {
this.millisDate = millisDate;
}
public Date getUnixTimeDate() {
return unixTimeDate;
}
public void setUnixTimeDate(Date unixTimeDate) {
this.unixTimeDate = unixTimeDate;
}
public Date getIso8601Date() {
return iso8601Date;
}
public void setIso8601Date(Date iso8601Date) {
this.iso8601Date = iso8601Date;
}
public Date getDefaultDate() {
return defaultDate;
}
public void setDefaultDate(Date defaultDate) {
this.defaultDate = defaultDate;
}
@Override
public String toString() {
return "Bean{" +
"millisDate=" + millisDate +
", unixTimeDate=" + unixTimeDate +
", iso8601Date=" + iso8601Date +
", dataFormatDate=" + dataFormatDate +
", defaultDate=" + defaultDate +
'}';
}
}
fastjson的测试类
public class Bean1 {
@JSONField(format = "millis")
private Date millisDate;
@JSONField(format = "unixtime")
private Date unixTimeDate;
// @JSONField(format = "iso8601")
@JSONField(serialzeFeatures = SerializerFeature.UseISO8601DateFormat)
private Date iso8601Date;
private Date defaultDate;
public Date getMillisDate() {
return millisDate;
}
public void setMillisDate(Date millisDate) {
this.millisDate = millisDate;
}
public Date getUnixTimeDate() {
return unixTimeDate;
}
public void setUnixTimeDate(Date unixTimeDate) {
this.unixTimeDate = unixTimeDate;
}
public Date getIso8601Date() {
return iso8601Date;
}
public void setIso8601Date(Date iso8601Date) {
this.iso8601Date = iso8601Date;
}
public Date getDefaultDate() {
return defaultDate;
}
public void setDefaultDate(Date defaultDate) {
this.defaultDate = defaultDate;
}
@Override
public String toString() {
return "Bean1{" +
"millisDate=" + millisDate +
", unixTimeDate=" + unixTimeDate +
", iso8601Date=" + iso8601Date +
", defaultDate=" + defaultDate +
'}';
}
}
运行结果:
fastjson2 全局配置format前序列化结果
{"dataFormatDate":"2024-12-27 11:22:48","defaultDate":"2024-12-27 11:22:48.404","iso8601Date":"2024-12-27T11:22:48.404+08:00","millisDate":1735269768404,"unixTimeDate":1735269768}
fastjson2 全局配置format后序列化结果
{"dataFormatDate":"2024-12-27 11:22:48","defaultDate":1735269768404,"iso8601Date":"2024-12-27T11:22:48.404+08:00","millisDate":1735269768404,"unixTimeDate":1735269768}
fastjson2 方法传入format序列化结果
{"dataFormatDate":"2024-12-27 11:22:48","defaultDate":"20241227","iso8601Date":"2024-12-27T11:22:48.404+08:00","millisDate":1735269768404,"unixTimeDate":1735269768}
fastjson 序列化结果
{"defaultDate":1735269768823,"iso8601Date":1735269768823,"millisDate":1735269768823,"unixTimeDate":1735269768}
fastjson2 反序列化结果: Bean{millisDate=Fri Dec 27 10:50:31 CST 2024, unixTimeDate=Fri Dec 27 10:50:31 CST 2024, iso8601Date=Fri Dec 27 10:50:31 CST 2024, dataFormatDate=Fri Dec 27 10:50:31 CST 2024, defaultDate=Fri Dec 27 10:50:31 CST 2024}