I could not think of a better way to formulate this question, but basically I want to save the name of a particular class in GSON (see "movement"):
{ "player" : { "position" : { "x" : 300, "y" : 400 }, "scale" : 1, "rotation" : 0, "sprite" : { "frames" : [ { "fileName" : "data/plane.png" } ], "duration" : 1 } }, "movementDelay" : { "elapsed" : 0, "started" : 0, "delay" : 150 }, "movement" : { "class" : "controller.TopDownGridMovement" } }
This is the class that contains the Movement interface that I want to use for deserialization:
public class PlayerController { private Player player; private DelayTimer movementDelay; private Movement movement; public PlayerController() { } [...] }
I wrote my own deserializer:
package gson; import java.lang.reflect.Type; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; import controller.Movement; public class MovementDeserialiser implements JsonDeserializer<Movement> { @Override public Movement deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { try { JsonObject obj = (JsonObject) json; Class clazz = Class.forName(obj.get("class").getAsString()); return (Movement) clazz.newInstance(); } catch (Exception e) { throw new JsonParseException(e.getMessage()); } } }
I registered a deserializer:
public void registerAdapters(GsonBuilder gsonBuilder) { gsonBuilder.registerTypeAdapter(Image.class, new ImageDeserialiser()); gsonBuilder.registerTypeAdapter(Button.class, new ButtonDeserialiser()); gsonBuilder.registerTypeAdapter(Animation.class, new AnimationDeserialiser()); gsonBuilder.registerTypeAdapter(Movement.class, new MovementDeserialiser()); }
Then I tried to deserialize the class containing the Movement interface:
playerController = gson.fromJson(new FileReader("data/player_data/player_data.json"), PlayerController.class);
But I get this error:
ERROR: Unable to invoke the no-args constructor for the interface controller. Traffic. Registering InstanceCreator with Gson for this type can solve this problem.
What do I need to do to make this work? The idea of ββspecifying the class to load came from the Spring bean config stuff - not sure if there is a better way to do this.
Oh, and from the reading I did, I decided that I did not need to create an InstanceCreator for Movement. In the end, I provide a custom deserializer ...
Greetings.