You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I created an abstract class Child with one concrete implementation Son. A reference to Child is used in Parent class as a member variable. Next we try to serialize an instance of Parent class.
Scenario 1 -
When no adapter is registered for Child class.
Output -
{"child":{"sonName":"s1","childName":"p1"}} //this is the correct, expected response
Scenario 2 -
When only a custom deserializer (which simply calls the default deserializer) adapter is registered for Child class.
Output -
{"child":{"childName":"p1"}} //Child class fields are missing in the response
Scenario 3 -
When both custom deserializer and a custom serializer are registered for Child class.
Output -
{"child":{"sonName":"s1","childName":"p1"}} //expected response
Question - Is it necessary to register a custom serializer along with a custom deserializer?
The code snippet to reproduce the above scenarios. Please register the appropriate adapters in the main method for each of the above scenarios -
`public class GsonAdapterTest {
abstract static class Child {
protected String childName;
public Child(String childName) {
this.childName = childName;
}
public Child() {
}
public String getChildName() {
return childName;
}
public void setChildName(String childName) {
this.childName = childName;
}
}
static class Son extends Child {
public String sonName;
public Son(String parentName, String sonName) {
super(parentName);
this.sonName = sonName;
}
public Son() {
}
public String getSonName() {
return sonName;
}
public void setSonName(String sonName) {
this.sonName = sonName;
}
}
static class Parent {
private Child child;
public Parent(Child child) {
this.child = child;
}
public Parent() {
}
public Child getChild() {
return child;
}
public void setChild(Child child) {
this.child = child;
}
}
public static void main(String[] args) {
try {
Gson gson = new GsonBuilder()
.registerTypeAdapter(Child.class, new ChildDeserializer())
.create();
Son son = new Son("p1", "s1");
Parent parent = new Parent(son);
System.out.println(gson.toJson(parent));
} catch (Exception e) {
e.printStackTrace();
}
}
static class ChildDeserializer implements JsonDeserializer<Child> {
@Override
public Child deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
return context.deserialize(json, typeOfT);
}
}
static class ChildSerializer implements JsonSerializer<Child> {
@Override
public JsonElement serialize(Child src, Type typeOfSrc, JsonSerializationContext context) {
return context.serialize(src);
}
}
}`
The text was updated successfully, but these errors were encountered:
Looks like #1787 fixed this issue. The next Gson version will include that fix.
The reason why in your code using registerTypeAdapter(Child.class, new ChildSerializer()) fixed this issue is because ChildSerializer calls context.serialize(src). This will end up using the adapter for the runtime type of src. In your case that seems to be safe because Child is an abstract class. However, in general calling context.serialize(src) should be avoided because it can lead to infinite recursion (the documentation of JsonSerializer.serialize warns about this).
Walkthrough -
I created an abstract class Child with one concrete implementation Son. A reference to Child is used in Parent class as a member variable. Next we try to serialize an instance of Parent class.
Scenario 1 -
When no adapter is registered for Child class.
Output -
{"child":{"sonName":"s1","childName":"p1"}} //this is the correct, expected response
Scenario 2 -
When only a custom deserializer (which simply calls the default deserializer) adapter is registered for Child class.
Output -
{"child":{"childName":"p1"}} //Child class fields are missing in the response
Scenario 3 -
When both custom deserializer and a custom serializer are registered for Child class.
Output -
{"child":{"sonName":"s1","childName":"p1"}} //expected response
Question - Is it necessary to register a custom serializer along with a custom deserializer?
The code snippet to reproduce the above scenarios. Please register the appropriate adapters in the main method for each of the above scenarios -
`public class GsonAdapterTest {
}`
The text was updated successfully, but these errors were encountered: