I have a structure where there is a group which may contain leaf items or other groups too, so I implemented the Composite design pattern using a "SavedItem" interface with 2 subclasses "Rectangle" which represents the leaf node and "Group" where Group contains an arraylist of SavedItem objects to implement this composition hierarchy. I used Gson to export the structure I have as a json file. The exported object is basically an arraylist of SavedItem objects and everything worked fine. However, the application requires loading a json file as well and converting it back to java objects, so I also used Gson but as I am trying to retrieve an arraylist of the interface "SavedItem" I am getting this exception:
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: Unable to invoke no-args constructor for interface SavedItem. Register an InstanceCreator with Gson for this type may fix this problem.
This is the "SavedItem" interface:
public interface SavedItem {
public String getId();
public String getDescription();
public Boolean getIsGroup();
public void addSavedItem(SavedItem savedItem);
}
This is the leaf node class "Rectangle" (of course with all setters and getters):
public class Rectangle implements SavedItem{
private String id;
private String type;
private String description;
private Point startingPoint ;
private double width;
private double height;
private boolean isGroup;
public Rectangle(){}
public Rectangle(Point startingPoint, double width, double height, String type , String description) {
this.id = "FIELD-" + UUID.randomUUID().toString();
this.startingPoint = startingPoint;
this.width = width;
this.height = height;
this.type= type;
this.description = description;
this.isGroup = false;
}
And this is the Group class (in addition to setters and getters):
public class Group implements SavedItem{
private String id;
private String description;
ArrayList<SavedItem> groupFields = new ArrayList<SavedItem>();
private boolean isGroup;
public Group(){}
public Group(String description) {
this.id = "GROUP-" + UUID.randomUUID().toString();
this.description = description;
this.isGroup = true;
}
The main object (called MedicalForm) contains this arraylist:
private ArrayList<SavedItem> StructuredFields = new ArrayList<>();
Creating the json file is done like this:
try {
Writer writer = new FileWriter(path+"/"+ form.getFormName()+".json");
Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonObject object = new JsonObject();
object.addProperty("id", form.getId());
object.addProperty("formName", form.getFormName());
JsonElement element = gson.toJsonTree(form.getStructuredFields());
object.add("StructuredFields", element);
object.addProperty("imageString", form.getImageString());
gson.toJson(object,writer);
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
And loading a json and converting it back to java objects is done like this:
JsonReader reader = new JsonReader(new FileReader(path));
Gson gson = new Gson();
MedicalForm response = gson.fromJson(reader, MedicalForm.class);
form.setId(response.getId());
form.setFormName(response.getFormName());
form.setStructuredFields(response.getStructuredFields());
form.setImageString(response.getImageString());
I searched for the problem and I found solutions saying I should add a default constructor and so I did in both Group and Rectangle classes in addition to the class where I am trying to convert json to java object. However, I can't add a constructor in the interface, and replacing the interface with a superclass will prevent the flexibility of casting. How can I solve this issue and convert the json properly to java objects?
Aucun commentaire:
Enregistrer un commentaire