首页 > 解决方案 > 如何使用 gson 和 JsonWriter 反序列化对象数组

问题描述

我有以下课程:

public class MeetingCenter {
    private String name;
    private List<MeetingRoom> meetingRoomList;
}

public class MeetingRoom {
    private MeetingCenter meetingCenter;
    private String code;
    private String name;
    private List<Reservation> reservationList;
}

public class Reservation {
    private MeetingRoom meetingRoom;
    private String owner;
}

我想创建一个具有以下模式的 JSON:

架构

这个方法在我调用 toJson() 方法的那一行抛出了一个异常:

private static void exportToJson(List<MeetingCenter> mcs) throws IOException {
    Gson gson = new Gson();
    String data = gson.toJson(mcs);

    JsonWriter writer = new JsonWriter(new FileWriter("export.json"));
    writer.setIndent("    "); // set indent

    writer.beginObject(); // document start
    writer.name("schema").value("PLUS4U.EBC.MCS.MeetingRoom_Schedule_1.0");
    writer.name("uri").value("ues:UCL-BT:UCL.INF/DEMO_REZERVACE:EBC.MCS.DEMO/MR001/SCHEDULE");
    writer.name("data").value(data);

    writer.endObject(); // document end
    writer.close();
}

例外:

Exception in thread "main" java.lang.StackOverflowError
    at java.lang.StringBuffer.append(StringBuffer.java:380)
    at java.io.StringWriter.write(StringWriter.java:77)
    at com.google.gson.stream.JsonWriter.beforeName(JsonWriter.java:614)
    at com.google.gson.stream.JsonWriter.writeDeferredName(JsonWriter.java:401)
    at com.google.gson.stream.JsonWriter.beginArray(JsonWriter.java:287)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:95)
    ....

标签: javajsongson

解决方案


您的对象都引用了它们的父对象。

GSON 查看 aMeetingCenter然后尝试序列化其子MeetingRooms。s对MeetingRooms 有引用MeetingCenter,所以 GSON 绕着圈转,直到你得到一个堆栈溢出。

要解决此问题,您可以确保只暴露孩子而不暴露父母。已经有很多问题表明了这一点。请参阅序列化期间的 Java Gson 排除字段

例如,您Reservation可能看起来像这样:

class Reservation {
    MeetingRoom meetingRoom;
    @Expose
    String owner;
}

我会把剩下的留给你。


writer.endArray()此外,当您尚未启动数组时,您有一个方法调用。删除该行。

writer.beginObject(); // document start
writer.name("schema").value("PLUS4U.EBC.MCS.MeetingRoom_Schedule_1.0");
writer.name("uri").value("ues:UCL-BT:UCL.INF/DEMO_REZERVACE:EBC.MCS.DEMO/MR001/SCHEDULE");
writer.name("data").value(data);

//writer.endArray(); removed
writer.endObject(); // document end
writer.close();

推荐阅读