无法使用 GsonConverterFactory 在 Retrofit 2.0 中将子类对象转换为请求主体 json
Can not convert Subclass object to request body json in Retrofit 2.0 with GsonConverterFactory
在我的例子中,当我将子 class 对象放入改造请求中时,它在请求正文中变为空白
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流程link Polymorphism with gson
我必须自己编写 Gson 转换器吗?
Gson 尝试序列化没有字段的 class 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()));
感谢@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
或任何根 class/interface 是这样它会自动处理所有可能的子类,因为更复杂的层次结构被添加到项目中 -不过目前不确定这种通用方法的任何缺点。
在我的例子中,当我将子 class 对象放入改造请求中时,它在请求正文中变为空白
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流程link Polymorphism with gson
我必须自己编写 Gson 转换器吗?
Gson 尝试序列化没有字段的 class 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()));
感谢@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
或任何根 class/interface 是这样它会自动处理所有可能的子类,因为更复杂的层次结构被添加到项目中 -不过目前不确定这种通用方法的任何缺点。