【发布时间】:2016-05-14 21:08:39
【问题描述】:
我正在使用 Retrofit 2 和 Gson,但在反序列化来自我的 API 的响应时遇到了问题。这是我的场景:
我有一个名为 Employee 的模型对象,它具有三个字段:id、name、age。
我有一个返回单个 Employee 对象的 API,如下所示:
{
"status": "success",
"code": 200,
"data": {
"id": "123",
"id_to_name": {
"123" : "John Doe"
},
"id_to_age": {
"123" : 30
}
}
}
还有一个Employee 对象列表,如下所示:
{
"status": "success",
"code": 200,
"data": [
{
"id": "123",
"id_to_name": {
"123" : "John Doe"
},
"id_to_age": {
"123" : 30
}
},
{
"id": "456",
"id_to_name": {
"456" : "Jane Smith"
},
"id_to_age": {
"456" : 35
}
},
]
}
这里需要考虑三个主要事项:
- API 响应在通用包装器中返回,重要部分位于
data字段中。 - API 以与模型上的字段不直接对应的格式返回对象(例如,取自
id_to_age的值需要映射到模型上的age字段) - API 响应中的
data字段可以是单个对象,也可以是对象列表。
如何使用Gson 实现反序列化,以便优雅地处理这三种情况?
理想情况下,我宁愿完全使用TypeAdapter 或TypeAdapterFactory 来完成此操作,而不是支付JsonDeserializer 的性能损失。最终,我想得到一个 Employee 或 List<Employee> 的实例,这样它就可以满足这个接口:
public interface EmployeeService {
@GET("/v1/employees/{employee_id}")
Observable<Employee> getEmployee(@Path("employee_id") String employeeId);
@GET("/v1/employees")
Observable<List<Employee>> getEmployees();
}
我发布的这个较早的问题讨论了我对此的第一次尝试,但它没有考虑上面提到的一些问题: Using Retrofit and RxJava, how do I deserialize JSON when it doesn't map directly to a model object?
【问题讨论】:
-
你说“我的 API”。如果你可以访问后端,你应该在服务器端更好地进行年龄和名称的序列化。
-
我没有访问权限。 “我的 API”是指我正在使用的 API。
-
为什么不创建简单的旧 Java 对象来表示您的 JSON 响应,然后将它们映射到您的 Employee 类?
-
这就是我为模型部分所做的(请参阅我帖子末尾的另一个链接),但我无法弄清楚如何做到这一点并处理通用包装器并处理事实上,包装器内的响应可以是对象或数组。
标签: android gson deserialization retrofit