For some unknown reason if I have:
class A{
int stars;
public int getStars(){
return stars;
}
public void setStarts(int stars){
this.stars = stars;
}
}
class B extends A{
int sunshines;
[getter and setter for sunshines]
}
class C{
List<A> classes;
[get and set for classes]
}
if I serialize an Object of type C I have only the fields of A in the serialized objects in the field classes (while I would expect to have the fields of B if the object is a B).
How to do that?
By default, GSON excludes transient and static fields from the serialization/deserialization process.
In this example you'll see how the Gson library handles the object fields. For object fields to be serialized into JSON string it doesn't need to use any annotations, it can even read private fields.
Serialization in the context of Gson means converting a Java object to its JSON representation. In order to do the serialization, we need to create the Gson object, which handles the conversion. Next, we need to call the function toJson() and pass the User object. Program output.
As you can see, Gson will ignore the unknown fields and simply match the fields that it's able to.
Gson 2.1 supports this out of the box:
import java.util.ArrayList;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class GsonInheritanceTest
{
public static void main(String[] args)
{
Gson gson = new GsonBuilder().setPrettyPrinting().create();
C c = new C();
c.classes = new ArrayList<A>();
c.classes.add(new A(1));
c.classes.add(new B(2, 3));
System.out.println(gson.toJson(c));
}
static class A
{
int stars;
A(int stars)
{
this.stars = stars;
}
}
static class B extends A
{
int sunshines;
B(int stars, int sunshines)
{
super(stars);
this.sunshines = sunshines;
}
}
static class C
{
List<A> classes;
}
}
The ouput is
{
"classes": [
{
"stars": 1
},
{
"sunshines": 3,
"stars": 2
}
]
}
I used Ivan's answer to clue me into a slightly more elegant solution - it's not perfect, but it worked well enough for me. I created a new JsonSerializer that throws away the type of A by casting it to an Object. It seems that when given a plain Object Gson looks at the actual type of the object instead of referring from the type of the variable that's passed in.
public static class ASerializer implements JsonSerializer<A> {
@Override
public JsonElement serialize( A in, Type type, JsonSerializationContext ctx ) {
return ctx.serialize( (Object) in );
}
}
You then pass the ASerializer
to a GsonBuilder
to get yourself a Gson instance to use:
GsonBuilder gb = new GsonBuilder();
gb.registerTypeAdapter( A.class, new ASerializer() );
Gson gson = gb.create();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With