淺析fastjson2時(shí)間序列化和反序列化的簡(jiǎn)單使用
在項(xiàng)目中將fastjson升級(jí)為fastjson2后,我們遇到了一些與fastjson不完全兼容的問(wèn)題。本文將探討下fastjson2的時(shí)間序列化和反序列化的簡(jiǎn)單使用。
時(shí)間序列化
在fastjson2中,若要將Java對(duì)象中的時(shí)間屬性序列化為JSON字符串,需使用@JSONField注解指定時(shí)間格式,或在序列化時(shí)通過(guò)方法參數(shù)傳入格式。
// 使用注解指定格式 @JSONField(format = "yyyy-MM-dd") private Date dateField; // 或者在序列化時(shí)通過(guò)方法參數(shù)傳入格式 String jsonString = JSON.toJSONString(bean, "yyyy-MM-dd");
時(shí)間反序列化
與序列化類似,將日期字符串反序列化為Java對(duì)象中的時(shí)間屬性時(shí),同樣可通過(guò)@JSONField注解或方法參數(shù)指定時(shí)間格式。
// 使用注解指定格式 @JSONField(format = "yyyy-MM-dd") private Date dateField; // 或者在反序列化時(shí)通過(guò)方法參數(shù)傳入格式 Bean bean = JSON.parseObject(jsonString, Bean.class, "yyyy-MM-dd");
fastjson2的默認(rèn)時(shí)間格式
在序列化時(shí)間時(shí),默認(rèn)格式為yyyy-MM-dd HH:mm:ss.SSS,這與Jackson和fastjson v1的默認(rèn)13位毫秒值時(shí)間戳格式有所不同。
fastjson2支持配置全局默認(rèn)時(shí)間格式,
- 序列化默認(rèn)時(shí)間格式可通過(guò)
JSON.configWriterDateFormat(format)設(shè)置。 - 反序列化默認(rèn)時(shí)間格式可通過(guò)
JSON.configReaderDateFormat(format)設(shè)置。
其中format值可以參考下文中的 format說(shuō)明。
fastjson2的隱藏功能
默認(rèn)兼容Jackson、Gson以及fastjson的注解,新一些的版本支持通過(guò)配置關(guān)閉Jackson和Gson的注解兼容,fastjson不支持關(guān)閉(也說(shuō)不定后面會(huì)支持、畢竟Jackson和Gson也是后面的版本才添加的支持配置關(guān)閉兼容)。
翻了下fastjson2的源碼,jackson的30多個(gè)注解基本都支持了,但是這個(gè)在官方文檔中卻沒(méi)有任何說(shuō)明。
格式化優(yōu)先級(jí)
在fastjson2中,時(shí)間格式的優(yōu)先級(jí)為:JSONField.format > 方法參數(shù)format > 全局配置。
format說(shuō)明
- iso8601:遵循ISO 8601標(biāo)準(zhǔn)格式,如
2024-12-27T11:22:48.404+08:00。 - millis:13位時(shí)間戳,。
- unixtime:10位時(shí)間戳,。
- 其他格式:遵循Java的
SimpleDateFormat標(biāo)準(zhǔn),如yyyy-MM-dd HH:mm:ss。
時(shí)間格式化組件
以下列出了Java日期和時(shí)間格式化中常用的組件及其含義:
特別注意,這里是區(qū)分大小寫(xiě)字母的,比如y和Y在日期格式化中有不同含義,y表示當(dāng)前日期歸屬年份,而Y表示當(dāng)前周歸屬的年份,這在年末時(shí)可能導(dǎo)致日期顯示錯(cuò)誤。
| 組件 | 描述 | 格式 | 示例 |
|---|---|---|---|
| G | 年代指示符 | 文本 | AD(公元) |
| y | 年份 | 年份 | 1996;96 |
| Y | 周年份(基于周計(jì)算) | 年份 | 2009;09 |
| M | 年中的月份(上下文敏感) | 月份 | July;Jul;07 |
| L | 年中的月份(獨(dú)立形式) | 月份 | July;Jul;07 |
| w | 年中的周數(shù) | 數(shù)字 | 27 |
| W | 月中的周數(shù) | 數(shù)字 | 2 |
| D | 年中的天數(shù) | 數(shù)字 | 189 |
| d | 月中的天數(shù) | 數(shù)字 | 10 |
| F | 月中的星期天數(shù) | 數(shù)字 | 2 |
| E | 星期中的天數(shù)名稱 | 文本 | Tuesday;Tue |
| u | 星期中的天數(shù)編號(hào)(1=星期一,...,7=星期日) | 數(shù)字 | 1 |
| a | 上午/下午標(biāo)記 | 文本 | PM |
| H | 一天中的小時(shí)(0-23) | 數(shù)字 | 0 |
| k | 一天中的小時(shí)(1-24) | 數(shù)字 | 24 |
| K | 上/下午中的小時(shí)(0-11) | 數(shù)字 | 0 |
| h | 上/下午中的小時(shí)(1-12) | 數(shù)字 | 12 |
| m | 小時(shí)中的分鐘 | 數(shù)字 | 30 |
| s | 分鐘中的秒 | 數(shù)字 | 55 |
| S | 毫秒 | 數(shù)字 | 978 |
| z | 時(shí)區(qū) | 一般時(shí)區(qū) | Pacific Standard Time;PST;GMT-08:00 |
| Z | 時(shí)區(qū) | RFC 822時(shí)區(qū) | -0800 |
| X | 時(shí)區(qū) | ISO 8601時(shí)區(qū) | -08;-0800;-08:00 |
時(shí)間格式化組件說(shuō)明
代碼示例
以下是使用fastjson2進(jìn)行時(shí)間序列化和反序列化的示例代碼。
代碼中用到的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>
測(cè)試類
public class DemoTest {
public static void main(String[] args) {
//序列化
testToJSONString();
//fastjson 序列化 和2進(jìn)行一個(gè)對(duì)比
testFastJson1ToJSON();
//解析為java對(duì)象
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前序列化結(jié)果");
System.out.println(JSON.toJSONString(bean));
String format = "millis";
JSON.configWriterDateFormat(format);
System.out.println("fastjson2 全局配置format后序列化結(jié)果");
System.out.println(JSON.toJSONString(bean));
System.out.println("fastjson2 方法傳入format序列化結(jié)果");
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 序列化結(jié)果");
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 反序列化結(jié)果: " + yyyyMMdd.toString());
}
}
fastjson2的測(cè)試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的測(cè)試類
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 +
'}';
}
}
運(yùn)行結(jié)果:
fastjson2 全局配置format前序列化結(jié)果
{"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后序列化結(jié)果
{"dataFormatDate":"2024-12-27 11:22:48","defaultDate":1735269768404,"iso8601Date":"2024-12-27T11:22:48.404+08:00","millisDate":1735269768404,"unixTimeDate":1735269768}
fastjson2 方法傳入format序列化結(jié)果
{"dataFormatDate":"2024-12-27 11:22:48","defaultDate":"20241227","iso8601Date":"2024-12-27T11:22:48.404+08:00","millisDate":1735269768404,"unixTimeDate":1735269768}
fastjson 序列化結(jié)果
{"defaultDate":1735269768823,"iso8601Date":1735269768823,"millisDate":1735269768823,"unixTimeDate":1735269768}
fastjson2 反序列化結(jié)果: 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}
到此這篇關(guān)于淺析fastjson2時(shí)間序列化和反序列化的簡(jiǎn)單使用的文章就介紹到這了,更多相關(guān)fastjson2時(shí)間序列化和反序列化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Redis內(nèi)存數(shù)據(jù)庫(kù)示例分析
Redis本身的內(nèi)容比較復(fù)雜。如果你上來(lái),你應(yīng)該研究一個(gè)細(xì)節(jié)點(diǎn),比如連接池和數(shù)據(jù)結(jié)構(gòu)。雖然可以直接了解某一點(diǎn)的詳細(xì)來(lái)源內(nèi)容,甚至盡快解決一些意外,但是容易淹沒(méi)在失眠的細(xì)節(jié)中,整體控制不了Redis2022-12-12
深入淺析Random類在高并發(fā)下的缺陷及JUC對(duì)其的優(yōu)化
這篇文章主要介紹了Random類在高并發(fā)下的缺陷及JUC對(duì)其的優(yōu)化 ,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-04-04
java存儲(chǔ)以及java對(duì)象創(chuàng)建的流程(詳解)
下面小編就為大家?guī)?lái)一篇java存儲(chǔ)以及java對(duì)象創(chuàng)建的流程(詳解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-05-05
Mybatis mapper標(biāo)簽中配置子標(biāo)簽package的坑及解決
這篇文章主要介紹了Mybatis mapper標(biāo)簽中配置子標(biāo)簽package的坑及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
Java EE過(guò)濾器優(yōu)先級(jí)控制的實(shí)例解讀
通過(guò)使用@Priority注解,可以控制JavaEE應(yīng)用中過(guò)濾器的執(zhí)行順序,在上面的示例中,我們通過(guò)設(shè)置不同的優(yōu)先級(jí),實(shí)現(xiàn)了TimeFilter和LogFilter的執(zhí)行順序控制2025-02-02
Feign利用自定義注解實(shí)現(xiàn)路徑轉(zhuǎn)義詳解
這篇文章主要講解一下如何通過(guò)注解實(shí)現(xiàn)對(duì)路由中的路徑進(jìn)行自定義編碼,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)或工作有一定的幫助,需要的可以參考一下2022-06-06

