Fastjson是一個Java語言編寫的高性能功能完善的JSON庫。javascript
fastjson採用首創的算法,將parse的速度提高到極致,超過全部json庫,包括曾經號稱最快的jackson。而且還超越了google的二進制協議protocol buf。java
http://code.alibabatech.com/mvn/releases/com/alibaba/fastjson/git
若是你使用了Maven,maven repository配置以下:github
<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這個類進行序列化和反序列化。sql
序列化就是把JavaBean對象轉化成JSON格式的文本。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有十幾個,你能夠按照本身的須要去選擇使用。iphone
fastjson直接支持日期類型數據的格式化,包括java.util.Date、java.sql.Date、java.sql.Timestamp、java.sql.Time。
缺省狀況下,fastjson將Date類型序列化爲long,這個使得序列化和反序列化的過程不會致使時區問題。如:
例如:
long
millis = 1324138987429L;
Date date =
new
Date(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"
|
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 =
new
A();
B b =
new
B(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) |
在某些場景,你可能須要定製序列化輸出,好比說,但願序列化採用以後採用"ID",而不是"id",你能夠使用@JSONField這個Annotation。
public
class
User {
@JSONField
(name=
"ID"
)
public
int
getId() { ... }
}
User user = ...;
JSON.toJSONString(user);
// {"ID":234}
|
若是你已經使用了json-lib,而且痛恨他蝸牛般的速度和羅嗦的API,建議你升級爲fastjson,fastjson能夠徹底兼容json-lib的序列化格式。
import
com.alibaba.fastjson.JSON;
import
com.alibaba.fastjson.serializer.JSONLibDataFormatSerializer;
import
com.alibaba.fastjson.serializer.JSONSerializerMap;
import
com.alibaba.fastjson.serializer.SerializerFeature;
private
static
final
SerializeConfig config;
static
{
config =
new
SerializeConfig();
config.put(java.util.Date.
class
,
new
JSONLibDataFormatSerializer());
// 使用和json-lib兼容的日期輸出格式
config.put(java.sql.Date.
class
,
new
JSONLibDataFormatSerializer());
// 使用和json-lib兼容的日期輸出格式
}
private
static
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兼容的字符串
public
static
String toCompatibleJSONString(Object object) {
return
JSON.toJSONString(object, config, features);
}
|
經過上面代碼中的toCompatibleJSONString方法,你就能夠實現徹底兼容json-lib了。
反序列化就是把JSON格式的文本轉化爲Java Bean對象。
經過指定類型信息,能夠很方便的將"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,
new
TypeReference<Map<String, User>>() {});
|
好比在網絡協議中,常常會存在這樣的組合:
[{
/*header*/}, {/*body*/
}]
|
fastjson對這種結構的反序列化有專門支持。
String text = ...;
// [{/* header */}, {/* body */}]
Type[] types =
new
Type[] {Header.
class
, Body.
class
};
List<Object> list = JSON.parseArray(text, types);
Header header = (Header) list.get(
0
);
Body body = (Body) list.get(
1
);
|
若是你的JavaBean沒有缺省構造函數,能夠使用@JSONCreator來指定構造函數
public
static
class
Entity {
private
final
int
id;
private
final
String name;
@JSONCreator
public
Entity(
@JSONField
(name =
"id"
)
int
id,
@JSONField
(name =
"name"
) String name){
this
.id = id;
this
.name = name;
}
public
int
getId() {
return
id; }
public
String getName() {
return
name; }
}
|
public
static
interface
Bean {
int
getId();
void
setId(
int
value);
String getName();
void
setName(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());
出自:
|