无法将Subclass对象转换为使用GsonConverterFactory在Retrofit 2.0中请求body json

时间:2016-06-02 10:27:17

标签: java android gson rx-java retrofit2

在我的情况下,当我将子类对象放入改装请求时,它在请求正文中变为空白

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);

现在我正在通过FbUserObject

networkAPI.createUserNew(fbUserObject).subscribe();

然后物体在体内变成空白。 看我的日志

 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)

我也会浏览此stackover流程链接Polymorphism with gson

我应该写自己的Gson转换器吗?

2 个答案:

答案 0 :(得分:4)

Gson尝试序列化没有字段的类User

您需要做的是将类型适配器注册到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()));

答案 1 :(得分:2)

感谢@pixel的回答 - 它帮助我们找到了正确的方向,所以我提出了更通用的解决方案,现在我又开心了:

    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();

我认为甚至可以使用Object而不是User或者根类/接口是什么,所以它会自动处理所有可能的子类,因为更复杂的层次结构被添加到项目中 - 不确定任何目前这种通用方法的缺点。