【问题标题】:Abstract class with Gson serialization/deserialization具有 Gson 序列化/反序列化的抽象类
【发布时间】:2020-10-09 12:03:40
【问题描述】:

我希望从 json 中获得 LinkedList<Request>。 pojo 看起来像这样:

@Data
@Builder
public class Request {
    private String id;
    private List<Parameter> parameters;
}

@Data
@SuperBuilder
public abstract class Parameter implements Serializable {
    private String key;
    public abstract Object getValue();
}

@Data
@SuperBuilder
@EqualsAndHashCode(callSuper = true)
public class StringParameter extends Parameter implements Serializable {
    private String value;
}

@Data
@SuperBuilder
@EqualsAndHashCode(callSuper = true)
public class PasswordParameter extends Parameter implements Serializable {
    private String value;
}

序列化工作正常,它生成 json,但它在反序列化时崩溃(可能是抽象类或/并且我期待 LinkedList 和/或 lombok 注释)? 我尝试编写一个 gson 反序列化器(通过谷歌搜索找到的一个相当标准的反序列化器),但它不起作用。

【问题讨论】:

  • 你不能这样做,除非你能在原则上区分具体参数(在结构上,StringParameterPasswordParameter 是等价的,没有办法重构初始类)。结构反序列化非常困难,因为它需要更多的计算和时间。一种可能的解决方案是将区分字段添加到 Parameter 以保存具体类型名称。见github.com/google/gson/blob/master/extras/src/main/java/com/…
  • RuntimeTypeAdapterFactory 没有与 Gson 捆绑在一起,因此您只需将其复制到您的代码库(这是人们通常使用它的方式)。但是,不确定添加 type 字段是否适用于 Lombok,因为 type 字段应该在任何 Parameter 子类中保持不变。

标签: java gson deserialization abstract-class


【解决方案1】:

感谢@fluffy 的建议,我设法跳过了编写自定义反序列化器并使用gson-extras 库中的RuntimeTypeAdapterFactory

public static void writeObjectToFile(Object object, String filePath) {
      RuntimeTypeAdapterFactory<Parameter> parameterAdapterFactory = RuntimeTypeAdapterFactory.of(Parameter.class, "type");
      parameterAdapterFactory.registerSubtype(StringParameter.class, "StringParameter");
      parameterAdapterFactory.registerSubtype(PasswordParameter.class, "PasswordParameter");
      Gson gson = new GsonBuilder().setPrettyPrinting().registerTypeAdapterFactory(parameterAdapterFactory).create();
      try {
          FileWriter fileWriter = new FileWriter(filePath);
          gson.toJson(object, fileWriter);
          fileWriter.flush();
          fileWriter.close();
      } catch (IOException e) {
          System.out.println(e.getMessage());
      }
  }

  public static LinkedList<Request> readObjectFromFile(String filePath) {
      RuntimeTypeAdapterFactory<Parameter> parameterAdapterFactory = RuntimeTypeAdapterFactory.of(Parameter.class, "type");
      parameterAdapterFactory.registerSubtype(StringParameter.class, "StringParameter");
      parameterAdapterFactory.registerSubtype(PasswordParameter.class, "PasswordParameter");
      Gson gson = new GsonBuilder().setPrettyPrinting().registerTypeAdapterFactory(parameterAdapterFactory).create();
      try {
          BufferedReader jsonBuffer = new BufferedReader(new FileReader(filePath));
          return gson.fromJson(jsonBuffer, new TypeToken<LinkedList<Request>>(){}.getType());
      } catch (FileNotFoundException e) {
          System.out.println(e.getMessage());
      }
      return  null;
  }

我也只保留了 lombok 注释,没有为我的 POJO 编写构造函数和 getter/setter

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-07
    • 2015-04-07
    • 1970-01-01
    • 1970-01-01
    • 2010-10-12
    • 1970-01-01
    • 2015-05-03
    相关资源
    最近更新 更多