如何使用 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:

http://img1.mukewang.com/628ddd950001df7605330306.jpg

这个方法在我调用 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)

    ....


Qyouu
浏览 185回答 2
2回答

肥皂起泡泡

@Expose 是避免 stackoverflow 异常的解决方案,但该语句writer.name("data").value(data);无效,因为数据将使用转义字符丰富。例如,您可以在数据字段中拥有"data": "{\"name\": \"center 1\" ... }"所以反序列化阶段可能会出现问题。我的实现为 MeetingCenter 类提出了一个 Container 类,可以在其中配置模式和 URI。/** Container class configures the schema and URI */public class Container {&nbsp; &nbsp; @Expose&nbsp; &nbsp; private String schema;&nbsp; &nbsp; @Expose&nbsp; &nbsp; private String uri;&nbsp; &nbsp; @Expose&nbsp; &nbsp; private List<MeetingCenter> data;}public class Reservation {&nbsp; &nbsp; private MeetingRoom meetingRoom;&nbsp; &nbsp; @Expose&nbsp; &nbsp; private String owner;}public class MeetingRoom {&nbsp; &nbsp; private MeetingCenter meetingCenter;&nbsp; &nbsp; @Expose&nbsp; &nbsp; private String code;&nbsp; &nbsp; @Expose&nbsp; &nbsp; private String name;&nbsp; &nbsp; @Expose&nbsp; &nbsp; private List<Reservation> reservationList;}public class MeetingCenter {&nbsp; &nbsp; @Expose&nbsp; &nbsp; private String name;&nbsp; &nbsp; @Expose&nbsp; &nbsp; private List<MeetingRoom> meetingRoomList;}public class Main {&nbsp; &nbsp; public static void main(String[] args){&nbsp; &nbsp; &nbsp; &nbsp; Container container = meetingCenterInitialization();&nbsp; &nbsp; &nbsp; &nbsp; GsonBuilder builder = new GsonBuilder();&nbsp; &nbsp; &nbsp; &nbsp; builder.setPrettyPrinting();&nbsp; &nbsp; &nbsp; &nbsp; // it is necessary to avoid stackoverflow&nbsp; &nbsp; &nbsp; &nbsp; builder.excludeFieldsWithoutExposeAnnotation();&nbsp; &nbsp; &nbsp; &nbsp; Gson gson = builder.create();&nbsp; &nbsp; &nbsp; &nbsp; String jsonString = gson.toJson(container);&nbsp; &nbsp; &nbsp; &nbsp; System.out.println(jsonString);&nbsp; &nbsp; &nbsp; &nbsp; Container container1 = gson.fromJson(jsonString, Container.class);&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("\n\n\n\n" + container1.getData().get(0).getName());&nbsp; &nbsp; }}主要方法的输出是{&nbsp; "schema": "PLUS4U.EBC.MCS.MeetingRoom_Schedule_1.0",&nbsp; "uri": "ues:UCL-BT:UCL.INF/DEMO_REZERVACE:EBC.MCS.DEMO/MR001/SCHEDULE",&nbsp; "data": [&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; "name": "center name",&nbsp; &nbsp; &nbsp; "meetingRoomList": [&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "code": "room 1",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;...

PIPIONE

您的对象都引用了它们的父对象。GSON 查看 aMeetingCenter然后尝试序列化其子MeetingRooms。s对MeetingRooms 有引用MeetingCenter,所以 GSON 绕着圈转,直到你得到一个堆栈溢出。要解决此问题,您可以确保只暴露孩子而不暴露父母。已经有很多问题表明了这一点。请参阅序列化期间的 Java Gson 排除字段。例如,您Reservation可能看起来像这样:class Reservation {&nbsp; &nbsp; MeetingRoom meetingRoom;&nbsp; &nbsp; @Expose&nbsp; &nbsp; String owner;}我会把剩下的留给你。writer.endArray()此外,当您尚未启动数组时,您有一个方法调用。删除该行。writer.beginObject(); // document startwriter.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(); removedwriter.endObject(); // document endwriter.close();
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java