抽象类与Gson序列化/反序列化

huangapple go评论70阅读模式
英文:

Abstract class with Gson serialization/deserialization

问题

我期望从一个 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 反序列化器(在网上找到的标准方式),但它没有完成工作。
英文:

I am expecting to get from a json a LinkedList<Request>.
The pojos look like this:

@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;
}

The serialization works fine, it generates the json, but it crashes at deserialization (maybe it's the abstract class or/and that I am expecting a LinkedList and/or the lombok annotations)?
I tryed writting a gson deserializer (quite a standard one found googling), but it doesn't do the job.

答案1

得分: 0

由于 @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 方法。

英文:

Thanks to @fluffy's suggestion, I managed to skip writing a custom deserialiser and making use of RuntimeTypeAdapterFactory from gson-extras library:

public static void writeObjectToFile(Object object, String filePath) {
RuntimeTypeAdapterFactory&lt;Parameter&gt; parameterAdapterFactory = RuntimeTypeAdapterFactory.of(Parameter.class, &quot;type&quot;);
parameterAdapterFactory.registerSubtype(StringParameter.class, &quot;StringParameter&quot;);
parameterAdapterFactory.registerSubtype(PasswordParameter.class, &quot;PasswordParameter&quot;);
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&lt;Request&gt; readObjectFromFile(String filePath) {
RuntimeTypeAdapterFactory&lt;Parameter&gt; parameterAdapterFactory = RuntimeTypeAdapterFactory.of(Parameter.class, &quot;type&quot;);
parameterAdapterFactory.registerSubtype(StringParameter.class, &quot;StringParameter&quot;);
parameterAdapterFactory.registerSubtype(PasswordParameter.class, &quot;PasswordParameter&quot;);
Gson gson = new GsonBuilder().setPrettyPrinting().registerTypeAdapterFactory(parameterAdapterFactory).create();
try {
BufferedReader jsonBuffer = new BufferedReader(new FileReader(filePath));
return gson.fromJson(jsonBuffer, new TypeToken&lt;LinkedList&lt;Request&gt;&gt;(){}.getType());
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
}
return  null;
}

I also kept only the lombok annotations and did not write constructors and getters/setters for my POJOs

huangapple
  • 本文由 发表于 2020年10月9日 20:03:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/64279695.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定