为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用 gson 和 JsonWriter 反序列化对象数组

如何使用 gson 和 JsonWriter 反序列化对象数组

Qyouu 2022-05-25 15:40:49
我有以下课程: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)    ....
查看完整描述

2 回答

?
肥皂起泡泡

TA贡献1829条经验 获得超6个赞

@Expose 是避免 stackoverflow 异常的解决方案,但该语句


writer.name("data").value(data);

无效,因为数据将使用转义字符丰富。例如,您可以在数据字段中拥有


"data": "{\"name\": \"center 1\" ... }"

所以反序列化阶段可能会出现问题。


我的实现为 MeetingCenter 类提出了一个 Container 类,可以在其中配置模式和 URI。


/** Container class configures the schema and URI */

public class Container {

    @Expose

    private String schema;

    @Expose

    private String uri;

    @Expose

    private List<MeetingCenter> data;

}


public class Reservation {

    private MeetingRoom meetingRoom;

    @Expose

    private String owner;

}


public class MeetingRoom {

    private MeetingCenter meetingCenter;

    @Expose

    private String code;

    @Expose

    private String name;

    @Expose

    private List<Reservation> reservationList;

}


public class MeetingCenter {

    @Expose

    private String name;

    @Expose

    private List<MeetingRoom> meetingRoomList;

}


public class Main {

    public static void main(String[] args){

        Container container = meetingCenterInitialization();


        GsonBuilder builder = new GsonBuilder();

        builder.setPrettyPrinting();

        // it is necessary to avoid stackoverflow

        builder.excludeFieldsWithoutExposeAnnotation();


        Gson gson = builder.create();


        String jsonString = gson.toJson(container);

        System.out.println(jsonString);



        Container container1 = gson.fromJson(jsonString, Container.class);

        System.out.println("\n\n\n\n" + container1.getData().get(0).getName());

    }

}

主要方法的输出是


{

  "schema": "PLUS4U.EBC.MCS.MeetingRoom_Schedule_1.0",

  "uri": "ues:UCL-BT:UCL.INF/DEMO_REZERVACE:EBC.MCS.DEMO/MR001/SCHEDULE",

  "data": [

    {

      "name": "center name",

      "meetingRoomList": [

        {

          "code": "room 1",


         ...


查看完整回答
反对 回复 2022-05-25
?
PIPIONE

TA贡献1829条经验 获得超9个赞

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


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();


查看完整回答
反对 回复 2022-05-25
  • 2 回答
  • 0 关注
  • 184 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信