gpt4 book ai didi

android - 使用 Gson 和 Retrofit 2 反序列化复杂的 API 响应

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:39:24 25 4
gpt4 key购买 nike

我正在使用 Retrofit 2 和 Gson,但在反序列化来 self 的 API 的响应时遇到了问题。这是我的场景:

我有一个名为 Employee 的模型对象,它具有三个字段:idnameage

我有一个 API 可以像这样返回一个单一的 Employee 对象:

{
"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
}
},
]
}

这里主要考虑三件事情:

  1. API 响应在通用包装器中返回,重要部分在 data 字段中。
  2. API 以不直接对应于模型字段的格式返回对象(例如,从 id_to_age 中获取的值需要映射到模型上的 age 字段)
  3. API 响应中的 data 字段可以是单个对象,也可以是对象列表。

我如何使用 Gson 实现反序列化以优雅地处理这三种情况?

理想情况下,我更愿意完全使用 TypeAdapterTypeAdapterFactory 来执行此操作,而不是支付 JsonDeserializer 的性能损失。最终,我想得到一个 EmployeeList<Employee> 的实例,它满足这个接口(interface):

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?

最佳答案

我建议使用 JsonDeserializer,因为响应中的嵌套级别不多,因此不会对性能造成太大影响。

类看起来像这样:

需要为通用响应调整服务接口(interface):

interface EmployeeService {

@GET("/v1/employees/{employee_id}")
Observable<DataResponse<Employee>> getEmployee(@Path("employee_id") String employeeId);

@GET("/v1/employees")
Observable<DataResponse<List<Employee>>> getEmployees();

}

这是一个通用的数据响应:

class DataResponse<T> {

@SerializedName("data") private T data;

public T getData() {
return data;
}
}

员工模型:

class Employee {

final String id;
final String name;
final int age;

Employee(String id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}

}

员工反序列化器:

class EmployeeDeserializer implements JsonDeserializer<Employee> {

@Override
public Employee deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {

JsonObject employeeObject = json.getAsJsonObject();
String id = employeeObject.get("id").getAsString();
String name = employeeObject.getAsJsonObject("id_to_name").entrySet().iterator().next().getValue().getAsString();
int age = employeeObject.getAsJsonObject("id_to_age").entrySet().iterator().next().getValue().getAsInt();

return new Employee(id, name, age);
}
}

响应的问题是 nameage 包含在一个 JSON 对象中,该对象在 Java 中转换为 Map,因此需要做更多的工作来解析

关于android - 使用 Gson 和 Retrofit 2 反序列化复杂的 API 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37231894/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com