Fastjson詳細介紹
簡介
Fastjson是一個Java語言編寫的高性能功能完善的JSON庫。
高性能
fastjson采用獨創的算法,將parse的速度提升到極致,超過所有json庫,包括曾經號稱最快的jackson。并且還超越了google的二進制協議protocol buf。
支持標準
- Fastjson完全支持http://json.org的標準,也是官方網站收錄的參考實現之一。 </ul>
- 支持各種JDK類型。包括基本類型、JavaBean、Collection、Map、Enum、泛型等。
- 支持循環引用 </ul>
- 不需要例外額外的jar,能夠直接跑在JDK上。 </ul>
- 支持JDK 5、JDK 6、Android、阿里云手機等環境。 </ul>
- Apache License 2.0
- 代碼托管在github.org上,項目地址是 https://github.com/AlibabaTech/fastjson </ul>
- fastjson有超過1500個testcase,每次構建都會跑一遍,豐富的測試場景保證了功能穩定。 </ul>
功能強大
無依賴
支持范圍廣
開源
測試充分
獲得fastjson
下載
http://code.alibabatech.com/mvn/releases/com/alibaba/fastjson/
maven
如果你使用了Maven,maven repository配置如下:
<repository> <id>opensesame</id> <name>Alibaba OpenSource Repsoitory</name> <url>http://code.alibabatech.com/mvn/releases/</url> <snapshots> <enabled>false</enabled> </snapshots></repository> |
pom.xml文件中加入依賴依賴:
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.1.14</version></dependency> |
序列化
一個JSON庫涉及的最基本功能就是序列化和反序列化。Fastjson支持java bean的直接序列化。你可以使用com.alibaba.fastjson.JSON這個類進行序列化和反序列化。
基本序列化
序列化就是把JavaBean對象轉化成JSON格式的文本。
Object o = ...;String text = JSON.toJSONString(o); |
在這個例子中,調用JSON.toJSONString方法,把對象o轉化為JSON格式的文本。
使用單引號
標準的JSON是使用雙引號的,javascript支持使用單引號格式的json文本,fastjson也支持這個特性,打開SerializerFeature.UseSingleQuotes這個特性就可以了了,例如:
Object o = ...;String text = JSON.toJSONString(o, SerializerFeature.UseSingleQuotes); |
fastjson序列化時可以選擇的SerializerFeature有十幾個,你可以按照自己的需要去選擇使用。
日期格式化
fastjson直接支持日期類型數據的格式化,包括java.util.Date、java.sql.Date、java.sql.Timestamp、java.sql.Time。
缺省情況下,fastjson將Date類型序列化為long,這個使得序列化和反序列化的過程不會導致時區問題。如:
例如:
longmillis = 1324138987429L;Date date = newDate(millis); System.out.println(JSON.toJSONString(date)); |
輸出的結果是
1324138987429 |
fastjson還提供了基于格式化輸出的SerializerFeature,例如:
JSON.toJSONString(date, SerializerFeature.WriteDateUseDateFormat); |
輸出的結果為:
"2011-12-18 00:23:07" |
你可以指定輸出日期的格式,比如修改為輸出毫秒:
JSON.toJSONStringWithDateFormat(date,"yyyy-MM-dd HH:mm:ss.SSS"); |
輸出的結果為:
"2011-12-18 00:23:07.429" |
使用WriteClassName特性
fastjson支持序列化時寫入類型信息,從而使得反序列化時不至于類型信息丟失。例如:
Color color = Color.RED;String text = JSON.toJSONString(color, SerializerFeature.WriteClassName);System.out.println(text); |
輸出結果:
{"@type":"java.awt.Color","r":255,"g":0,"b":0,"alpha":255} |
由于序列化帶了類型信息,使得反序列化時能夠自動進行類型識別,例如:
String text = ...; // {"@type":"java.awt.Color","r":255,"g":0,"b":0,"alpha":255}Color color = (Color) JSON.parse(text); |
瀏覽器和設備兼容
fastjson缺省的序列化內容,是對序列化結果緊湊做了優化配置,使得序列化之后長度更小,但是這種優化配置是對一些瀏覽器和設備不兼容的。比如說在iphone上兼容emoji(繪文字)。
JSON.toJSONString(o, SerializerFeature.BrowserCompatible); |
循環引用
很多場景中,我們需要序列化的對象中存在循環引用,在許多的json庫中,這會導致stackoverflow。在功能強大的fastjson中,你不需要擔心這個問題。例如:
A a = newA();B b = newB(a);a.setB(b);String text = JSON.toJSONString(a); // {"b":{"a":{"$ref":".."}}}A a1 = JSON.parseObject(text, A.class);Assert.assertTrue(a1 == a1.getB().getA()); |
引用是通過"$ref"來表示的
| 引用 | 描述 |
|---|---|
| "$ref":".." | 上一級 |
| "$ref":"@" | 當前對象,也就是自引用 |
| "$ref":"$" | 根對象 |
| "$ref":"$.children.0" | 基于路徑的引用,相當于 root.getChildren().get(0) |
使用@JSONField Annotation
在某些場景,你可能需要定制序列化輸出,比如說,希望序列化采用之后采用"ID",而不是"id",你可以使用@JSONField這個Annotation。
publicclass User { @JSONField(name="ID") publicint getId() { ... }}User user = ...;JSON.toJSONString(user);// {"ID":234} |
從json-lib中升級
如果你已經使用了json-lib,并且痛恨他蝸牛般的速度和羅嗦的API,建議你升級為fastjson,fastjson可以完全兼容json-lib的序列化格式。
importcom.alibaba.fastjson.JSON;importcom.alibaba.fastjson.serializer.JSONLibDataFormatSerializer;importcom.alibaba.fastjson.serializer.JSONSerializerMap;importcom.alibaba.fastjson.serializer.SerializerFeature; privatestatic final SerializeConfig config;static{ config = newSerializeConfig(); config.put(java.util.Date.class,newJSONLibDataFormatSerializer());// 使用和json-lib兼容的日期輸出格式 config.put(java.sql.Date.class,newJSONLibDataFormatSerializer());// 使用和json-lib兼容的日期輸出格式} privatestatic final SerializerFeature[] features = { SerializerFeature.WriteMapNullValue, // 輸出空置字段 SerializerFeature.WriteNullListAsEmpty,// list字段如果為null,輸出為[],而不是null SerializerFeature.WriteNullNumberAsZero,// 數值字段如果為null,輸出為0,而不是null SerializerFeature.WriteNullBooleanAsFalse,// Boolean字段如果為null,輸出為false,而不是null SerializerFeature.WriteNullStringAsEmpty// 字符類型字段如果為null,輸出為"",而不是null }; // 序列化為和JSON-LIB兼容的字符串publicstatic String toCompatibleJSONString(Object object) { returnJSON.toJSONString(object, config, features);} |
通過上面代碼中的toCompatibleJSONString方法,你就可以實現完全兼容json-lib了。
反序列化
反序列化就是把JSON格式的文本轉化為Java Bean對象。
指定Class信息反序列化
通過指定類型信息,可以很方便的將"JSON文本"反序列化為"Java Bean"對象,例如:
String text = ...; // {"r":255,"g":0,"b":0,"alpha":255}Color color = JSON.parseObject(text, Color.class); |
類型集合的反序列化
這個接口類似于parseObject
String text = ...; // [{ ... }, { ... }]List<User> users = JSON.parseArray(text, User.class); |
泛型的反序列化
如果你需要返回一個帶泛型的對象,例如List<User>、Map<String, User>,你可以使用TypeReference來傳入類型信息。
String text = ...; // {"name":{"name":"ljw",age:18}}Map<String, User> userMap = JSON.parseObject(text, newTypeReference<Map<String, User>>() {}); |
組合類型集合的反序列化
比如在網絡協議中,經常會存在這樣的組合:
[{/*header*/}, {/*body*/}] |
fastjson對這種結構的反序列化有專門支持。
String text = ...; // [{/* header */}, {/* body */}]Type[] types = newType[] {Header.class, Body.class};List<Object> list = JSON.parseArray(text, types);Header header = (Header) list.get(0);Body body = (Body) list.get(1); |
使用@JSONCreator來指定構造函數來創建對象
如果你的JavaBean沒有缺省構造函數,可以使用@JSONCreator來指定構造函數
publicstatic class Entity { privatefinal int id; privatefinal String name; @JSONCreator publicEntity(@JSONField(name = "id")intid,@JSONField(name = "name") String name){ this.id = id; this.name = name; } publicint getId() { returnid; } publicString getName() { returnname; }} |
把JSON文本反序列化為一個原型接口
publicstatic interface Bean { intgetId(); voidsetId(intvalue); String getName(); voidsetName(String value);}String text = "{\"id\":123, \"name\":\"chris\"}";Bean bean = JSON.parseObject(text, Bean.class);// 按接口調用Assert.assertEquals(123, bean.getId());Assert.assertEquals("chris", bean.getName());bean.setId(234);Assert.assertEquals(234, bean.getId());出自: |