fastJSON從0到1
Fastjson是一個(gè)Java應(yīng)用程序中操作JSON對(duì)象的Java類庫,它可以將Java對(duì)象轉(zhuǎn)換為JSON格式的字符串,并將JSON字符串轉(zhuǎn)換為Java對(duì)象。Fastjson的速度非常快,是目前市面上最快的JSON庫之一。
快速入門1.添加maven依賴
<dependency>
????<groupId>com.alibaba</groupId>
????<artifactId>fastjson</artifactId>
????<version>1.2.76</version>
</dependency>
2.將Java對(duì)象轉(zhuǎn)換為JSON字符串
import?com.alibaba.fastjson.JSON;
public?class?User?{
????private?String?name;
????private?int?age;
????//?getter、setter方法
}
public?class?Main?{
????public?static?void?main(String[]?args)?{
????????User?user?=?new?User();
????????user.setName("Tom");
????????user.setAge(20);
????????String?jsonString?=?JSON.toJSONString(user);
????????System.out.println(jsonString);?//?{"age":20,"name":"Tom"}
????}
}
3.將JSON字符串轉(zhuǎn)換為Java對(duì)象
import?com.alibaba.fastjson.JSON;
public?class?User?{
????private?String?name;
????private?int?age;
????//?getter、setter方法
}
public?class?Main?{
????public?static?void?main(String[]?args)?{
????????String?jsonString?=?"{\"age\":20,\"name\":\"Tom\"}";
????????User?user?=?JSON.parseObject(jsonString,?User.class);
????????System.out.println(user.getName());?//?Tom
????????System.out.println(user.getAge());?//?20
????}
}
常用API
1.將Java對(duì)象轉(zhuǎn)換為JSON字符串
public?static?String?toJSONString(Object?object);
public?static?String?toJSONString(Object?object,?SerializerFeature...?features);
示例:
User?user?=?new?User();
user.setName("Tom");
user.setAge(20);
String?jsonString1?=?JSON.toJSONString(user);
System.out.println(jsonString1);?//?{"age":20,"name":"Tom"}
String?jsonString2?=?JSON.toJSONString(user,?SerializerFeature.WriteMapNullValue);
System.out.println(jsonString2);?//?{"name":"Tom","age":20,"school":null}
2.將JSON字符串轉(zhuǎn)換為Java對(duì)象
public?static?<T>?T?parseObject(String?text,?Class<T>?clazz);
public?static?<T>?T?parseObject(String?text,?TypeReference<T>?type);
示例:
String?jsonString?=?"{\"age\":20,\"name\":\"Tom\"}";
User?user?=?JSON.parseObject(jsonString,?User.class);
System.out.println(user.getName());?//?Tom
System.out.println(user.getAge());?//?20
3.轉(zhuǎn)換為JSONObject或JSONArray對(duì)象
public?static?JSONObject?parseObject(String?text);
public?static?JSONArray?parseArray(String?text);
示例:
String?jsonString?=?"{\"name\":\"Tom\",\"age\":20}";
JSONObject?jsonObject?=?JSON.parseObject(jsonString);
System.out.println(jsonObject.getString("name"));?//?Tom
System.out.println(jsonObject.getIntValue("age"));?//?20
JSONArray?jsonArray?=?JSON.parseArray("[\"Tom\",20]");
System.out.println(jsonArray.get(0));?//?Tom
System.out.println(jsonArray.getIntValue(1));?//?20
序列化特征
Fastjson序列化時(shí),可以設(shè)置一些特殊的序列化特征。
示例:
import?com.alibaba.fastjson.JSON;
import?com.alibaba.fastjson.serializer.SerializerFeature;
public?class?User?{
????private?String?name;
????private?int?age;
????//?getter、setter方法
}
public?class?Main?{
????public?static?void?main(String[]?args)?{
????????User?user?=?new?User();
????????user.setName("Tom");
????????user.setAge(20);
????????String?jsonString?=?JSON.toJSONString(user,?SerializerFeature.PrettyFormat,?SerializerFeature.WriteDateUseDateFormat);
????????System.out.println(jsonString);
????????/**
?????????*?{
?????????*?????"age":?20,
?????????*?????"name":?"Tom"
?????????*?}
?????????*/
????}
}
常用序列化特征:
| 序列化特征名稱 | 功能 |
|---|---|
| WriteMapNullValue | 是否輸出值為null的字段,默認(rèn)為false |
| WriteNullListAsEmpty | 是否輸出空的List,默認(rèn)為false |
| WriteNullStringAsEmpty | 是否輸出空的字符串,默認(rèn)為false |
| WriteNullBooleanAsFalse | 是否輸出為null的布爾字段,默認(rèn)為false |
| PrettyFormat | 是否格式化輸出,默認(rèn)為false |
| BeanToArray | 是否序列化Bean時(shí)輸出class名稱,默認(rèn)為false |
| WriteDateUseDateFormat | 是否使用DateFormat進(jìn)行日期格式化輸出,默認(rèn)為false |
到此我們了解了Fastjson的使用方法以及常用API和序列化特征。Fastjson是JSON解析庫中的佼佼者,在實(shí)際項(xiàng)目中也有廣泛的應(yīng)用。Fastjson使用簡單、兼容性好、效率高,值得開發(fā)者使用。
fastjson使用中有哪些注意點(diǎn)-
安全問題:Fastjson在高版本(1.2.24及之前)中存在反序列化漏洞,攻擊者可以通過構(gòu)造惡意JSON數(shù)據(jù)來執(zhí)行任意代碼。因此,建議使用最新版本的Fastjson庫。
-
JSON數(shù)據(jù)格式問題:Fastjson對(duì)于不符合JSON數(shù)據(jù)格式的數(shù)據(jù)可能會(huì)出現(xiàn)解析錯(cuò)誤。例如,對(duì)象或數(shù)組的括號(hào)不匹配,或者鍵或值不用雙引號(hào)括起來等。建議在使用Fastjson時(shí)確保JSON數(shù)據(jù)符合規(guī)范。
-
Java對(duì)象中的屬性問題:Fastjson在序列化Java對(duì)象時(shí),會(huì)忽略值為null的屬性,這個(gè)可以通過設(shè)置SerializerFeature.WriteMapNullValue來進(jìn)行處理。而如果屬性有g(shù)etter方法但無setter方法,F(xiàn)astjson在序列化時(shí)也無法將屬性值傳遞給JSON,需要添加setter方法或使用注解 @JSONField(serialize = false) 來處理。另外,序列化時(shí)不能處理自引用或循環(huán)引用的對(duì)象,可以使用SerializerFeature.DisableCircularReferenceDetect來禁止處理循環(huán)引用。
-
特殊字符問題:Fastjson在轉(zhuǎn)換時(shí)會(huì)對(duì)特殊字符進(jìn)行轉(zhuǎn)義,例如雙引號(hào)、單引號(hào)、換行符等。但需要注意的是,在某些特殊場(chǎng)景下,這些轉(zhuǎn)義可能會(huì)導(dǎo)致問題,例如將JSON數(shù)據(jù)作為HTML的一部分輸出,需要對(duì)特殊字符進(jìn)行進(jìn)一步處理。
-
注解問題:Fastjson提供了一些注解用于定制序列化或反序列化的行為,如 @JSONField、@JSONType 等。需要了解這些注解及其使用方法,才能更好地使用Fastjson。
總的來說,使用Fastjson需要注意數(shù)據(jù)格式、Java對(duì)象屬性、特殊字符、注解等問題,才能正確高效地進(jìn)行JSON序列化和反序列化。
生產(chǎn)中如何優(yōu)雅使用fastjson在生產(chǎn)環(huán)境中,我們可以考慮以下幾點(diǎn)來優(yōu)雅地使用Fastjson:
-
盡量選擇最新版本的Fastjson,并及時(shí)更新:Fastjson在不斷地進(jìn)行優(yōu)化和修復(fù),我們應(yīng)該選擇最新版本的Fastjson,并及時(shí)更新以獲得更好的性能和安全性。
-
確認(rèn)JSON數(shù)據(jù)格式正確:在使用Fastjson時(shí),我們需要確認(rèn)JSON數(shù)據(jù)格式正確,避免因格式不正確而導(dǎo)致解析出錯(cuò)。我們可以使用在線JSON格式校驗(yàn)工具或?qū)I(yè)的JSON格式校驗(yàn)庫來進(jìn)行格式校驗(yàn)。
-
使用合適的Fastjson配置:Fastjson提供了很多配置選項(xiàng)可以優(yōu)化序列化和反序列化的性能,我們應(yīng)該理解這些配置選項(xiàng)并選擇合適的配置以獲得更好的性能和安全性。
-
對(duì)Java對(duì)象進(jìn)行優(yōu)化:Fastjson在序列化和反序列化Java對(duì)象時(shí),會(huì)對(duì)對(duì)象的所有屬性都進(jìn)行處理。如果Java對(duì)象中存在一些不需要處理的屬性,可以使用 @JSONField 注解或 SerializerFeature.IgnoreNonFieldGetter 等配置選項(xiàng)來忽略這些屬性,從而提升性能。
-
使用Fastjson擴(kuò)展功能:Fastjson提供了很多擴(kuò)展功能,如日期格式化、JSON對(duì)象/數(shù)組操作等,我們可以學(xué)習(xí)并使用這些功能,使代碼更簡潔和優(yōu)雅。
-
處理Fastjson安全問題:Fastjson在早期版本中存在反序列化漏洞,為了避免漏洞帶來的安全問題,我們應(yīng)該使用最新版的Fastjson,控制輸入數(shù)據(jù)的來源和格式,對(duì)反序列化的結(jié)果進(jìn)行安全性驗(yàn)證等。
我們可以通過選擇最新版的Fastjson、確認(rèn)JSON格式、配置選項(xiàng)、對(duì)象優(yōu)化、擴(kuò)展功能和安全處理等方面來優(yōu)雅地使用Fastjson。
fastjson使用了哪些設(shè)計(jì)模式在Fastjson中,有以下常見的設(shè)計(jì)模式:
-
工廠模式:Fastjson使用工廠模式來創(chuàng)造解析器(JSONReader、JSONWriter)和序列化器(JSONSerializer)。對(duì)于解析器,使用了JSONToken的工廠模式。
-
建造者模式:Fastjson使用建造者模式來創(chuàng)建JSON對(duì)象和JSONArray對(duì)象。
-
單例模式:在Fastjson中,一些重要的類(例如SerializerFeature)使用單例模式來確保整個(gè)應(yīng)用程序中只有一個(gè)實(shí)例存在。
-
靜態(tài)工具類模式:Fastjson中定義了一些靜態(tài)工具類,如JSON、JSONObject等,這些工具類提供了一些方便的方法來操作JSON數(shù)據(jù)。
-
策略模式:Fastjson使用策略模式來完成序列化和反序列化。通過使用Serializer和Deserializer接口,F(xiàn)astjson允許用戶自定義序列化和反序列化邏輯。
-
觀察者模式:Fastjson在解析JSON字符串時(shí),通過觸發(fā)事件來通知觀察者的方式,在不同的解析階段(例如開始、結(jié)束、鍵和值等)觸發(fā)不同的事件通知觀察者。
Fastjson使用了多種不同的設(shè)計(jì)模式,這些模式幫助Fastjson更好地實(shí)現(xiàn)了它的功能,同時(shí)也使得它的代碼更加清晰易懂和易于維護(hù)。
核心API設(shè)計(jì)當(dāng)我們要進(jìn)行Java對(duì)象與JSON的轉(zhuǎn)換時(shí),F(xiàn)astjson提供了兩個(gè)主要的API:toJSONString()方法和parseObject()方法。toJSONString()方法可以將Java對(duì)象序列化為JSON格式字符串;parseObject()方法可以將JSON格式字符串反序列化為Java對(duì)象。這兩個(gè)API非常方便易用,具體實(shí)現(xiàn)細(xì)節(jié)如下:
toJSONString()方法的實(shí)現(xiàn)細(xì)節(jié)
toJSONString()方法是Fastjson序列化Java對(duì)象的核心方法。首先,F(xiàn)astjson會(huì)通過反射機(jī)制來獲取Java對(duì)象的所有屬性和屬性值,然后根據(jù)這些屬性和屬性值構(gòu)建JSON格式的字符串,并返回。要注意的是,F(xiàn)astjson對(duì)于不同數(shù)據(jù)類型的Java對(duì)象會(huì)進(jìn)行不同的處理,例如對(duì)于Java的Date類型,F(xiàn)astjson會(huì)自動(dòng)將日期格式化為字符串返回。
public?static?String?toJSONString(Object?object,?boolean?prettyFormat)?{
??????SerializeWriter?out?=?new?SerializeWriter((Writer)null,?defaultBufferSize);
??????try?{
??????????JSONSerializer?serializer?=?new?JSONSerializer(out);
??????????if?(prettyFormat)?{
??????????????serializer.config(SerializerFeature.PrettyFormat,?true);
??????????}
??????????serializer.write(object);
??????????return?out.toString();
??????}?finally?{
??????????out.close();
??????}
??}
parseObject()方法的實(shí)現(xiàn)細(xì)節(jié)
parseObject()方法是Fastjson反序列化JSON字符串的核心方法。首先,F(xiàn)astjson會(huì)根據(jù)JSON格式字符串的語法規(guī)則,將JSON格式字符串解析為JSON對(duì)象,然后根據(jù)Java對(duì)象對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu),將JSON對(duì)象轉(zhuǎn)換成Java對(duì)象,最后返回Java對(duì)象。需要注意的是,F(xiàn)astjson支持對(duì)于泛型類型、復(fù)合對(duì)象等的反序列化操作。
public?static?final?<T>?T?parseObject(String?json,?TypeReference<T>?type,?Feature...?features)?{
??????if?(json?==?null)?{
??????????return?null;
??????}?else?{
??????????Object?object?=?JSON.parse(json,?features);
??????????return?cast(object,?type);
除了以上的兩個(gè)API,F(xiàn)astjson還提供了很多其他方便易用的API,例如自定義序列化和反序列化器、JSON格式化輸出、數(shù)組和集合的處理以及數(shù)據(jù)類型的轉(zhuǎn)換等,在實(shí)際使用中可以根據(jù)需要進(jìn)行選擇,增加應(yīng)用程序的性能和擴(kuò)展性。
比如:
自定義序列化和反序列化器
Fastjson 提供了 SerializeFilter 和 ValueFilter 等接口,可以使用這些接口來自定義序列化和反序列化的方式。其中,SerializeFilter 用于在序列化時(shí)過濾部分字段,實(shí)現(xiàn)類似于 @JsonIgnore 和 @JsonProperty 的功能;ValueFilter 用于在序列化時(shí)修改字段的值,可以用來實(shí)現(xiàn)一些自定義轉(zhuǎn)換邏輯。
JSON 格式化輸出
Fastjson 提供了 SerializerFeature.PrettyFormat 配置項(xiàng),可以輸出帶有縮進(jìn)和換行符的美化 JSON 字符串,可以在調(diào)試時(shí)使用。
數(shù)組和集合的處理
Fastjson 支持將數(shù)組和集合類型的對(duì)象序列化為 JSON 字符串,并提供了一些方便的操作方法,比如 JSONArray.add() 和 JSONArray.get() 等,可以用來操作 JSONArray 對(duì)象;另外,F(xiàn)astjson 還提供了 TypeReference接口,可以用來獲取泛型類型的實(shí)際類型。
數(shù)據(jù)類型的轉(zhuǎn)換
Fastjson 支持將 JSON 字符串自動(dòng)轉(zhuǎn)換成 Java 對(duì)象,需要滿足對(duì)象中屬性名和 JSON 中鍵名一致,并且 JSON 中鍵名與對(duì)象中屬性名大小寫敏感。同時(shí),F(xiàn)astjson 還支持將 Java 對(duì)象轉(zhuǎn)換成 JSON 字符串、將基本類型的值轉(zhuǎn)換成包裝類型,以及將字符串類型的值轉(zhuǎn)換成其他數(shù)據(jù)類型等。
Fastjson 提供了很多強(qiáng)大的 API,可以在實(shí)際開發(fā)中幫助我們實(shí)現(xiàn)更加靈活和可擴(kuò)展的應(yīng)用程序,并提高了應(yīng)用程序的性能和可維護(hù)性。
fastJson不同版本的特性及bug修復(fù)情況Fastjson 從 1.x 版本至今已經(jīng)經(jīng)歷了很多年的發(fā)展,其各個(gè)版本都有不同的新增特性和重要的 bug 修復(fù)。下面就是 Fastjson 不同版本的特性和 bug 修復(fù)情況:
Fasjson 1.x 版本特性
Fastjson 1.x 版本是 Fastjson 最初發(fā)布的版本,其特性包括:
-
支持將 JSON 字符串轉(zhuǎn)換成 Java 對(duì)象;
-
支持將 Java 對(duì)象序列化成 JSON 字符串;
-
支持將 Java 對(duì)象序列化成 JSON 流;
-
支持 JSON 與 JavaBean 的自動(dòng)轉(zhuǎn)換;
-
可以使用 @JSONField 注解來映射屬性名;
-
支持自定義對(duì)象序列化方式;
-
支持將 JSON 模板轉(zhuǎn)換成 JavaBean。
Fastjson 1.x 版本 bug 修復(fù)
Fastjson 1.x 版本主要修復(fù)了以下重要的 bug:
-
修復(fù)某些情況下會(huì)導(dǎo)致 JSON 解析錯(cuò)誤的問題;
-
修復(fù)在某些環(huán)境中會(huì)導(dǎo)致內(nèi)存泄露的問題;
-
解決在某些情況下無法正確地序列化 BigDecimal 類型的問題;
-
修復(fù)某些情況下重復(fù)反序列化可能會(huì)導(dǎo)致屬性丟失的問題;
-
修復(fù)某些情況下 JSON 解析會(huì)出現(xiàn)錯(cuò)誤的問題。
Fastjson 2.x 版本特性
Fastjson 2.x 版本是 Fastjson 的重要更新版本,其特性包括:
-
支持自定義序列化和反序列化器;
-
支持 JSON 格式化輸出;
-
支持將數(shù)組和集合類型的對(duì)象序列化為 JSON 字符串;
-
支持將 Java 對(duì)象轉(zhuǎn)換成 JSON 字符串;
-
支持通過 getter 和 setter 方法來訪問對(duì)象的屬性值;
-
支持將 Java 對(duì)象轉(zhuǎn)換成 JSON 流;
-
支持對(duì)枚舉類型的序列化和反序列化;
-
支持針對(duì)某些字段指定序列化為 null 值或不序列化;
-
支持反序列化時(shí)自動(dòng)轉(zhuǎn)換數(shù)據(jù)類型。
Fastjson 2.x 版本 bug 修復(fù)
Fastjson 2.x 版本主要修復(fù)了以下重要的 bug:
-
修復(fù)某些情況下可能會(huì)導(dǎo)致空指針異常的問題;
-
解決某些情況下某些對(duì)象類型無法正確解析的問題;
-
修復(fù)某些情況下 JSON 字符串中出現(xiàn)轉(zhuǎn)義字符導(dǎo)致解析錯(cuò)誤的問題;
-
修復(fù)某些情況下無法正確地序列化枚舉類型的問題。
Fastjson 3.x 版本特性
Fastjson 3.x 版本是 Fastjson 的最新版本,其特性包括:
-
支持通過注解控制對(duì)象屬性和 JSON 鍵的映射規(guī)則;
-
支持自定義型轉(zhuǎn)換器;
-
支持注解指定日期格式;
-
支持多環(huán)境下的自動(dòng)引入依賴。
Fastjson 3.x 版本 bug 修復(fù)
Fastjson 3.x 版本主要修復(fù)了以下重要的 bug:
-
修復(fù)某些情況下會(huì)導(dǎo)致 JSON 字符串亂碼的問題;
-
解決某些情況下某些對(duì)象類型無法正確解析的問題;
-
修復(fù)某些情況下無法正確地序列化枚舉類型的問題;
-
修復(fù)某些情況下 JSON 解析會(huì)出現(xiàn)錯(cuò)誤的問題。
需要注意的是,由于每個(gè)版本中存在大量的功能和 bug 修復(fù),這里只對(duì)某些重要的特性和 bug 進(jìn)行了概括介紹,更多的信息可以查看 Fastjson 的官方網(wǎng)站。
