alibaba / fastjson2

🚄 FASTJSON2 is a Java JSON library with excellent performance.
Apache License 2.0
3.79k stars 495 forks source link

[BUG] 序列化的对象若包含 get开头的方法并且返回对象本身,JSONObject.toJSONString 报错 #2966

Open D-etfox opened 2 months ago

D-etfox commented 2 months ago

问题描述

序列化的对象若包含 get开头的方法并且返回对象本身 Caused by: com.alibaba.fastjson2.JSONException: level too large : 2048

环境信息

重现步骤

@Data
@Accessors(chain = true)
public class DataSource2 implements java.io.Serializable {
    private static final long serialVersionUID = -2484324543464304657L;
    private String name;
    private String sex;
    private Integer age;

    public static List<DataSource2> getData() {
        DataSource2 dataSource = new DataSource2()
                .setName("张三")
                .setSex("男")
                .setAge(24);
        return Arrays.asList(dataSource);
    }

    public DataSource2 getXXXXX() {
        return new DataSource2();
    }

    public static void main(String[] args) {
        System.out.println(JSONObject.toJSONString(DataSource2.getData()));
    }

}

期待的正确结果

序列化时,过滤掉没有字段对应的 getXXX 方法,比如我对象不存在某个字段,若对象中有 getXXX 方法,转换的 JSON 串也包含 xXX 字段

相关日志输出

Exception in thread "main" com.alibaba.fastjson.JSONException: level too large : 2048 at com.alibaba.fastjson.JSON.toJSONString(JSON.java:1653) at com.d.demo.java.DataSource2.main(DataSource2.java:61) Caused by: com.alibaba.fastjson2.JSONException: level too large : 2048

CodePlayer commented 2 months ago

首先,你描述的"期待的正确结果"似乎有些自相矛盾,前面说要 "过滤掉",后面又说 "也要包含"

其次,你这个不属于 bug,不管是 Fastjson 还是 Jackson 也好,都会遵循 JavaBean 规范,将 getXxx() 这种 getter 视为属性。

在你的 Java 类中,又存在无限循环嵌套。所以报这个错是正常的,这是你代码本身的问题。

如果你不想输出这个属性,你可以在该方法上加一个注解 @JSONField(serialize = false) 即可排除该方法(也可用于任意字段)。

如果你只想输出存在的字段,那么可以如下这样:

JSON.toJSONString(obj, JSONWriter.Feature.FieldBased); // 只基于类的字段进行JSON序列化输出