Cannot convert subclass object to request json body in Retrofit 2.0 using GsonConverterFactory

In my case, when I put a subclass object in a modification request, it is empty in the request body

interface User{ // my super interface } class FbUser implements User{ // my sub class public String name; public String email; } interface APIInterface{ @POST(APIConstants.LOGIN_URL) Observable<LoginAPIResponse> createUserNew(@Body User user); } Retrofit retrofit = new Retrofit.Builder() .baseUrl(baseUrl) .addConverterFactory(GsonConverterFactory.create(new Gson())) .addCallAdapterFactory(RxErrorHandlingCallAdapterFactory.create()) .client(okHttpClient) .build(); APIInterface networkAPI = retrofit.create(APIInterface.class); 

now i am going through FbUserObject

 networkAPI.createUserNew(fbUserObject).subscribe(); 

then the object becomes empty in the body. see my magazine

  D/OkHttp: Content-Type: application/json; charset=UTF-8 D/OkHttp: Content-Length: 2 D/OkHttp: Accept: application/json D/OkHttp: TT-Mobile-Post: post D/OkHttp: {} D/OkHttp: --> END POST (2-byte body) 

I am also viewing this stack stream link. Polymorphism with gson

Should I write my own Gson converter?

+5
source share
2 answers

Gson is trying to serialize a User class that has no fields.

What you need to do is register the type adapter for gson:

  retrofitBuilder.addConverterFactory(GsonConverterFactory.create(new GsonBuilder() .registerTypeAdapter(User.class, new JsonSerializer<User>() { @Override public JsonElement serialize(User src, Type typeOfSrc, JsonSerializationContext context) { if (src instanceof FbUser ) { return context.serialize(src, FbUser.class); } return context.serialize(src); } }).create())); 
+3
source

Thanks to @pixel for his answer - it helped digging in the right direction, so I came up with a more general solution, and now I'm happy again:

  Gson gson = new GsonBuilder() .registerTypeAdapter(User.class, new JsonSerializer<User>() { @Override public JsonElement serialize(User src, Type typeOfSrc, JsonSerializationContext context) { return context.serialize(src, src.getClass()); } }) .create(); 

I think that you can use Object instead of User or regardless of which root class / interface is such that it automatically processes all possible subclasses, since more complex hierarchies are added to the project - they are not sure of any drawbacks of such a general approach in this moment.

0
source

All Articles