Search code examples
javagsondeserializationabstract-class

Abstract class with Gson serialization/deserialization


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.


Solution

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

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