• notice
  • Congratulations on the launch of the Sought Tech site

The $ref problem of fastjson string to JSON

Conclusion first:

When fastjson converts objects into strings, if the same object is encountered, reference detection is enabled by default to write the same object as a reference.

Official website documentation: https://github.com/alibaba/fastjson/wiki

Background of the problem:

During the development process, a third-party topology map component was used. When the json string of the graph generated by the component is converted into a JSON object using fastjson, the error is as follows:

Exception in thread "main" com.alibaba.fastjson.JSONException: illegal ref, int

Later, when locating the following string parsing, an error occurs:

public class test {    public static void main(String[] args) {
        String str1 = "{\"$position\":{\"$ref\":21}}";
        String str2 = "{\"position\":{\"ref\":21}}";
        JSONObject json = JSONObject.parseObject(str1);

There is no problem parsing str2, but parsing str1 reports an error Exception in thread "main" com.alibaba.fastjson.JSONException: illegal ref, int

At the beginning, it was judged that the $ symbol was caused by a special symbol, so there is no problem in parsing str2 after removing it.

Then test and remove the first $

String str1 = "{\"position\":{\"$ref\":21}}";

Still an error: Exception in thread "main" com.alibaba.fastjson.JSONException: illegal ref, int

Then the problem arises with the second one $refThen I suspect that $ref is like a reserved field and cannot be used, so I modified it to

String str1 = "{\"position\":{\"$reff\":21}}";

Then the call is JSONObject.parseObject(str1);indeed normal.

Check the official website information: fastjson supports circular references and is turned on by default.

If there are identical objects, fastjson will enable reference mode by default.

{"$ref":"$"}reference root object
{"$ref":"@"}quote yourself
{"$ref":".."}reference parent object
{"$ref":"../.."}parent object referencing parent object
{"$ref":"$.members[0].reportTo"}path-based references

The official website also gives instructions:

When serialized JSON is transmitted to browsers or other languages, these JSON parsers do not support circular references, resulting in data loss. You can turn off fastjson's circular reference support. Turning off reference detection can also improve the performance of serialization.

global configuration close

  JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.DisableCircularReferenceDetect.getMask();

non-global shutdown

  JSON.toJSONString(obj, SerializerFeature.DisableCircularReferenceDetect);

To sum up, our string includes "$ref", fastjson thinks this is a reference mode, but the value of the reference is incorrect, resulting in an error.

There are two solutions mentioned above, one is global and the other is non-global.

We use non-global, then the following code is correct ✅

public class test {    public static void main(String[] args) {
        String str1 = "{\"$position\":{\"$reff\":21}}";
        JSONObject json = JSONObject.parseObject(str1, Feature.DisableCircularReferenceDetect);


Technical otaku

Sought technology together

Related Topic


Leave a Reply