FastJson的SerializerFeature序列化特性說明
FastJson 簡單使用
我們在使用fastjson的時候,一般來講,只需要使用最簡單的API,例如
String text = JSONObject.toJSONString(obj); //序列化
VO vo = JSONObject.parseObject("{...}", VO.class); //反序列化
SerializerFeature
但是如果我們希望我們的JSON對象在序列化和反序列化有一些特殊的要求,例如使用單引號而不是雙引號,我們可以通過配置來達到。
#{'a':'a','aa':'aa','ab':'ab','b':{'a':{"$ref":".."},'name':'B'},'name':'A'}
JSONObject.toJSONString(obj, SerializerFeature.UseSingleQuotes, SerializerFeature.WriteMapNullValue,SerializerFeature.MapSortField);
public enum SerializerFeature {
QuoteFieldNames,
UseSingleQuotes,
WriteMapNullValue,
WriteEnumUsingToString,
WriteEnumUsingName,
UseISO8601DateFormat,
WriteNullListAsEmpty,
WriteNullStringAsEmpty,
WriteNullNumberAsZero,
WriteNullBooleanAsFalse,
SkipTransientField,
SortField,
/** @deprecated */
@Deprecated
WriteTabAsSpecial,
PrettyFormat,
WriteClassName,
DisableCircularReferenceDetect,
WriteSlashAsSpecial,
BrowserCompatible,
WriteDateUseDateFormat,
NotWriteRootClassName,
/** @deprecated */
DisableCheckSpecialChar,
BeanToArray,
WriteNonStringKeyAsString,
NotWriteDefaultValue,
BrowserSecure,
IgnoreNonFieldGetter,
WriteNonStringValueAsString,
IgnoreErrorGetter,
WriteBigDecimalAsPlain,
MapSortField;
}
SerializerFeature 說明
名稱 | 含義 | 備註 |
---|---|---|
QuoteFieldNames | 輸出key時是否使用雙引號,默認爲true | |
UseSingleQuotes | 使用單引號而不是雙引號,默認爲false | |
WriteMapNullValue | 是否輸出值爲null的字段,默認爲false | |
WriteEnumUsingToString | Enum輸出name()或者original,默認爲false | |
WriteEnumUsingName | enum值序列化爲其Name,默認爲true | |
UseISO8601DateFormat | Date使用ISO8601格式輸出,默認爲false | |
WriteNullListAsEmpty | List字段如果爲null,輸出爲[],而非null | |
WriteNullStringAsEmpty | 字符類型字段如果爲null,輸出爲”“,而非null | |
WriteNullNumberAsZero | 數值字段如果爲null,輸出爲0,而非null | |
WriteNullBooleanAsFalse | Boolean字段如果爲null,輸出爲false,而非null | |
SkipTransientField | 如果是true,類中的Get方法對應的Field是transient,序列化時將會被忽略。默認爲true | |
SortField | 按字段名稱排序後輸出。默認爲false | |
WriteTabAsSpecial | 把\t做轉義輸出,默認爲false | 不推薦 |
PrettyFormat | 結果是否格式化,默認爲false | 不推薦 |
WriteClassName | 序列化時寫入類型信息,默認爲false。反序列化是需用到 | 不推薦 |
DisableCircularReferenceDetect | 消除對同一對象循環引用的問題,默認爲false | 不推薦 |
WriteSlashAsSpecial | 對斜槓’/’進行轉義 | 不推薦 |
BrowserCompatible | 將中文都會序列化爲\uXXXX格式,字節數會多一些,但是能兼容IE 6,默認爲false | 不推薦 |
WriteDateUseDateFormat | 全局修改日期格式,默認爲false。 | 不推薦 |
DisableCheckSpecialChar | 一個對象的字符串屬性中如果有特殊字符如雙引號,將會在轉成json時帶有反斜槓轉移符。如果不需要轉義,可以使用這個屬性。默認爲false | 不推薦 |
NotWriteRootClassName | 含義 | 不推薦 |
BeanToArray | 將對象轉爲array輸出 | 不推薦 |
WriteNonStringKeyAsString | 將屬性key寫爲String | 不推薦 |
NotWriteDefaultValue | 不設默認值 | 不推薦 |
BrowserSecure | 不推薦 | |
IgnoreNonFieldGetter | 忽略沒有getter方法的屬性 | 不推薦 |
WriteNonStringValueAsString | 不是String的字段寫爲String | |
IgnoreErrorGetter | 忽略掉getter方法出錯的屬性 | |
WriteBigDecimalAsPlain | 大數字寫成文本 | |
MapSortField | 字段按照TreeMap排序,默認false |
WriteEnumUsingName || WriteEnumUsingToString
目前版本的fastjson默認對enum對象使用WriteEnumUsingName屬性,因此會將enum值序列化爲其Name。
使用WriteEnumUsingToString方法可以序列化時將Enum轉換爲toString()的返回值;同時override toString函數能夠將enum值輸出需要的形式。但是這樣做會帶來一個問題,對應的反序列化使用的Enum的靜態方法valueof可能無法識別自行生成的toString(),導致反序列化出錯。
如果將節省enum序列化後的大小,可以將enum序列化其ordinal值,保存爲int類型。fastJson在反序列化時,如果值爲int,則能夠使用ordinal值匹配,找到合適的對象。
fastjson要將enum序列化爲ordinal只需要禁止WriteEnumUsingName feature。
首先根據默認的features排除WriteEnumUsingName,然後使用新的features序列化即可。
int features=SerializerFeature.config(JSONObject.DEFAULT_GENERATE_FEATURE, SerializerFeature.WriteEnumUsingName, false)
JSONObject.toJSONString(obj,features,SerializerFeature.EMPTY);
DisableCircularReferenceDetect
當進行toJSONString的時候,默認如果重用對象的話,會使用引用的方式進行引用對象。
[
{
"$ref": "$.itemSkuList[0].itemSpecificationList[0]"
},
{
"$ref": "$.itemSkuList[1].itemSpecificationList[0]"
}
]
循環引用
很多場景中,我們需要序列化的對象中存在循環引用,在許多的json庫中,這會導致stackoverflow。在功能強大的fastjson中,你不需要擔心這個問題。例如:
@Test
public void test(){
A a = new A();
B b = new B(a);
a.setB(b);
String text = JSONObject.toJSONString(a);
System.out.println(text);//{"b":{"a":{"$ref":".."},"name":"B"},"name":"A"}
A a1 = JSONObject.parseObject(text, A.class);
System.out.println(a1 == a1.getB().getA());//true
String text2 = JSONObject.toJSONString(a,SerializerFeature.DisableCircularReferenceDetect);//throw java.lang.StackOverflowError
}
@Data
class A{
String name ;
B b;
public A(){
this.name = "A";
}
}
@Data
class B{
String name ;
A a;
public B(){
this.name = "B";
}
public B(A a){
this.name = "B";
this.a = a;
}
}
引用是通過"$ref"來表示的
引用描述
"$ref":".." 上一級
"$ref":"@" 當前對象,也就是自引用
"$ref":"$" 根對象
"$ref":"$.children.0" 基於路徑的引用,相當於 root.getChildren().get(0)
WriteDateUseDateFormat
JSONObject.DEFFAULT_DATE_FORMAT = “yyyy-MM-dd”;
JSONObject.toJSONString(obj, SerializerFeature.WriteDateUseDateFormat);