fastjson 1.2.41
FastJson 問題
在json對象中有多個地方引用了相同的對象,在經過幾次轉換轉為json字符串的時候會出現(xiàn)占位符,
然后使用fastjson 解析字符串也能正確解析,但使用其他json類庫解析,無法正常還原數(shù)據(jù),還是占位符
/**
* FastJson 問題
* 測試 JSONArray(幾個元素有關聯(lián),引用了相同得對象) -> 轉為List -> 加入到 JSONObject 中 -> 最后轉為 json 字符串 打印的時候(最后一步得時候會出現(xiàn)占位符)
* -> 然后再轉為 JSONObject 的時候,非FastJson解析會出現(xiàn)問題(fastJson 解析正常,但是其他json類庫處理時,不會對占位符處理,最后直接就原樣的將值解析成占位符)
* 測試
* testTransfer1 僅僅數(shù)據(jù)一樣,但是實際上是幾個不同的對象(數(shù)據(jù)相同,對象不同),經過上述變化,未出現(xiàn)占位符
* testTransfer2 是從某一元素上取得數(shù)據(jù)(同一個對象,在json對象中,多個地方都有引用)在添加到該jsonArray 上,經過上述變化,會出現(xiàn)占位符
*/
@Test
public void name() {
// testTransfer1();
testTransfer2();
}
private void testTransfer1() {
// [{"one":1,"two":2,"tickets":[{"one":2,"two":3},{"one":3,"two":4}]},{"one":2,"two":3},{"one":3,"two":4}]
String str = "[{\"one\":1,\"two\":2,\"tickets\":[{\"one\":2,\"two\":3},{\"one\":3,\"two\":4}]},{\"one\":2,\"two\":3},{\"one\":3,\"two\":4}]";
JSONArray array = JSON.parseArray(str);
List<Object> objects = array.toJavaList(Object.class);
JSONObject object = new JSONObject();
object.put("list", objects);
System.out.println(object);
// 經過測試發(fā)現(xiàn)如果,不直接用從某個元素中取數(shù)據(jù),在添加到該jsonArray 本身,即使他們數(shù)據(jù)有重合的(數(shù)據(jù)相同,但不是同一個對象),也不會出現(xiàn) 占位符的現(xiàn)象
}
private void testTransfer2() {
// [{"one":1,"two":2,"tickets":[{"one":2,"two":3},{"one":3,"two":4}]]
String str = "[{\"one\":1,\"two\":2,\"tickets\":[{\"one\":2,\"two\":3},{\"one\":3,\"two\":4}]}]";
JSONArray array = JSON.parseArray(str);
// 這里添加
JSONArray tickets = array.getJSONObject(0).getJSONArray("tickets");
for (int i = 0; i < tickets.size(); i++) {
array.add(tickets.get(i));
}
List<Object> list = array.toJavaList(Object.class);
// 以下代碼說明 FastJson 在之后 轉為 json 字符串 ,然后再解析為 json 對象時處理正常(能正常解析)
JSONObject object = new JSONObject();
object.put("list",list);
String jsonStr = object.toJSONString();
System.out.println(jsonStr);
JSONArray list1 = JSON.parseObject(jsonStr).getJSONArray("list");
System.out.println(list1);
// 切換 為 其他 json類庫處理,例如:jackson
ObjectMapper mapper = new ObjectMapper();
try {
Object o = mapper.readValue(jsonStr, Object.class);
System.out.println(o);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
// 內部 從 某一個 元素取出數(shù)據(jù),在添加到 jsonArray 上, 經過 上述轉換 (JSONArray(幾個元素有關聯(lián)) -> 轉為List -> 加入到 JSONObject 中 -> 轉為 json 字符串),最后會變成這樣
// {"list":[{"tickets":[{"one":2,"two":3},{"one":3,"two":4}],"one":1,"two":2},{"$ref":"$.list[0].tickets[0]"},{"$ref":"$.list[0].tickets[1]"}]}
}
/**
* 禁用 fastjson 的 循環(huán)引用檢測
* 使用 SerializerFeature.DisableCircularReferenceDetect
*/
private void testTransfer3() {
String str = "[{\"one\":1,\"two\":2,\"tickets\":[{\"one\":2,\"two\":3},{\"one\":3,\"two\":4}]}]";
JSONArray array = JSON.parseArray(str);
// 這里添加
JSONArray tickets = array.getJSONObject(0).getJSONArray("tickets");
for (int i = 0; i < tickets.size(); i++) {
array.add(tickets.get(i));
}
// 全局關閉
// JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.DisableCircularReferenceDetect.getMask();
// 該次解析關閉
// 轉為 json 字符串的時候,禁用了 fastjson 的 循環(huán)檢測引用特性
String s = array.toJSONString(array, SerializerFeature.DisableCircularReferenceDetect);
// System.out.println(array.toJSONString());
System.out.println(s);
}
由于springboot 默認使用 jackson 處理json 請求,所以需要注意
由于時間問題,這個地方只是發(fā)現(xiàn)情況會出現(xiàn)這種問題,至于對象引用會不會出現(xiàn)這種問題,沒有進行實驗,也沒有對fastjson 源碼進行解讀