Ankur Samarya
Ankur Samarya

Reputation: 229

Can not convert Subclass object to request body json in Retrofit 2.0 with GsonConverterFactory

In My case when I put sub class object in retrofit request it goes blank in 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 passing FbUserObject

networkAPI.createUserNew(fbUserObject).subscribe();

then object goes blank in body. see my log

 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 also go through this stackover flow link Polymorphism with gson

Should i have to write my own Gson Converter?

Upvotes: 9

Views: 2433

Answers (2)

vir us
vir us

Reputation: 10735

Thanks to @pixel for his answer - it helped to dig into the right direction so I've came up with more generic 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 one can even use Object instead of User or whatever the root class/interface is so it handles all possible subclasses automatically as more complex hierarchies are added to the project - not sure about any drawbacks of such a generic approach at the moment though.

Upvotes: 2

pixel
pixel

Reputation: 26503

Gson tries to serialize class User which does not have fields.

What you need to do is to register type adapter to 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()));

Upvotes: 6

Related Questions