Gson Forgot To Register A Type Adapter?
How to Serialize and Deserialize Interfaces in Java Using Gson
Writer: Mauricio Silva Manrique
What is Gson?
Gson is a Java Library widely used to catechumen Java Objects into their JSON representation and vice versa.
Getting Started
Permit'south start past creating a new Java project. We can call information technology "InterfaceSerialization".
Nosotros demand to add the gson library in our projection in order for us to use information technology. If you are using Maven, add the latest version of gson to the POM file.
<dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.3.1</version> </dependency>
Stride 1:
Now, let'due south create our Java interface. This time I volition be using "Cars" as an instance. I love cars, who doesn't?
Our interface declares iii features that all cars share.
public interface Automobile { Cord model(); int maxSpeed(); Cord type(); }
Footstep 2:
Let's now create our Java classes that will implement our "Car" interface. I will be using "Lexus" and "Acura" (my favorite brands) for this example.
Let'due south define our Lexus class:
public class Lexus implements Car { private int maxSpeed; private Cord type; private int rankingAmongSedans; private Cord model; public Lexus(Cord model, int maxSpeed, String type, int rankingAmongSedans) { this.model = model; this.maxSpeed = maxSpeed; this.type = type; this.rankingAmongSedans = rankingAmongSedans; } public String model() { render model; } public int maxSpeed() { return maxSpeed; } public String type() { render type; } public int getRankingAmongSedans() { return rankingAmongSedans; } @Override public String toString(){ return "Model: " + model + ", Max speed: " + maxSpeed + " km/h, Type: " + type + ", Ranking: " + rankingAmongSedans ; } }
Step 3:
In the aforementioned way we take to ascertain our Acura class
public class Acura implements Motorcar{ individual int maxSpeed; private String blazon; private Cord model; public Acura(String model, int maxSpeed, Cord type) { this.model = model; this.maxSpeed = maxSpeed; this.type = type; } public String model() { return aught; } public int maxSpeed() { render maxSpeed; } public String type() { return blazon; } @Override public String toString() { return "Model: " + model + ", Max speed: " + maxSpeed + " km/h, Type: " + type; } }
Notice that the Lexus grade contains an extra field called "rankingAmongSedans". This volition help us to distinguish between the ii and prove that our serialization works properly.
Footstep 4:
Now allow'southward define our examination course:
public class Test { public static void main(Cord[] args) { //Allow'southward initialize our sample array of cars Car cars[] = new Car[]{new Lexus("Lexus Is", 260, "Sedan", three), new Acura("Acura Mdx", 193, "Suv")}; //Create our gson example Gson gson = new Gson(); //Let'southward serialize our array Cord carsJsonFormat = gson.toJson(cars, Machine[].form); //Permit's Impress our serialized arrya Organisation.out.println("Cars in Json Format: " + carsJsonFormat); } }
In this class, we are basically creating an array of "Cars" with two car objects, one being of Class Blazon Lexus, and the other i of Class Type Acura
So we instantiate a gson object called "Gson" and proceed to serialize our array. Finally we print our array in JSON format.
Our output should look like this:
Cars in JSON format:
[{"maxSpeed":260,"type":"Sedan","rankingAmongSedans":3,"model":"Lexus Is"},{"maxSpeed":193,"type":"Suv","model":"Acura Mdx"}]
It seems that everything went fine, our array of cars is printed in JSON format; however, what happens when nosotros try to deserialize the String back to an array of Car Objects?
Let's add this line lawmaking after our print statement and endeavour to re run our exam again.
Automobile [] carJsonArray = gson.fromJson(carsJsonFormat, Automobile[].class);
Oops, did you become this? RunTimeException: "Unable to invoke no-args constructor for interface Machine. Register an InstanceCreator with Gson for this type may fix this problem."
click to view in a new tab
Gson doesn't take way to place which "Auto Object" we are trying to deserialize. Nosotros need to register a Type Adapter that will assist gson differentiate the objects.
Step v: (The solution)
So let's ascertain a Generic Interface Adapter (so we are non but restricted to our car interface) that will override serialize and deserialize methods.
The magic happens in this form, as nosotros define a mapping structure to distinguish our Car Objects, where "CLASSNAME" is the key to get the object's course proper noun, and "DATA" is the key that maps the actual JSON object.
public grade InterfaceAdapterimplements JsonSerializer , JsonDeserializer { private static terminal String CLASSNAME = "CLASSNAME"; private static final Cord DATA = "Information"; public T deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { JsonObject jsonObject = jsonElement.getAsJsonObject(); JsonPrimitive prim = (JsonPrimitive) jsonObject.get(CLASSNAME); String className = prim.getAsString(); Class klass = getObjectClass(className); return jsonDeserializationContext.deserialize(jsonObject.get(Information), klass); } public JsonElement serialize(T jsonElement, Type blazon, JsonSerializationContext jsonSerializationContext) { JsonObject jsonObject = new JsonObject(); jsonObject.addProperty(CLASSNAME, jsonElement.getClass().getName()); jsonObject.add together(Information, jsonSerializationContext.serialize(jsonElement)); return jsonObject; } /****** Helper method to go the className of the object to exist deserialized *****/ public Class getObjectClass(String className) { attempt { return Class.forName(className); } catch (ClassNotFoundException e) { //eastward.printStackTrace(); throw new JsonParseException(e.getMessage()); } } } }
Pace 6:
Now, permit's become back to our test class and add the registerTypeAdapter to our gson object. Since we are using a customized gson object, we demand to construct it with "gsonBuilder".
Let's supervene upon Gson gson = new Gson(); with:
//Create our gson instance GsonBuilder builder = new GsonBuilder(); builder.registerTypeAdapter(Automobile.class, new InterfaceAdapter()); Gson gson = builder.create();
Now that we have registered our InterfaceAdapter, we'll add these lines of lawmaking to print our results:
//Let's print our motorcar objects to verify System.out.println("\n**********************************************************************"); System.out.println("My favorite Cars of 2015"); for(Car aCar : carJsonArray){ Organization.out.println(aCar); } System.out.println("**********************************************************************");
Permit's test again and see what happens. After running our exam class, we should encounter the following output: Cars in JSON Format:
[{"CLASSNAME":"Lexus","Information":{"maxSpeed":260,"type":"Sedan","rankingAmongSedans":3,"model":"Lexus Is"}},{"CLASSNAME":"Acura","DATA":{"maxSpeed":193,"type":"Suv","model":"Acura Mdx"}} ]
**********************************************************************
My favorite Cars of 2015
Model: Lexus Is, Max speed: 260 km/h, Type: Sedan, Ranking: 3
Model: Acura Mdx, Max speed: 193 km/h, Type: Suv
**********************************************************************
Nosotros were able to achieve our goal using gson past just adding an interface adapter. It's upwardly to you how to customize the serialization of unlike information types.
Source: https://technology.finra.org/code/serialize-deserialize-interfaces-in-java.html
Posted by: damicopriout37.blogspot.com
0 Response to "Gson Forgot To Register A Type Adapter?"
Post a Comment