当前位置: 首页 > 知识库问答 >
问题:

使用Retrofit和RxJava,当JSON没有直接映射到模型对象时,如何反序列化它?

融唯
2023-03-14

我所使用的API以“平面”格式返回对象(以及包含它们的对象),我很难让它优雅地使用Registfit和RXJava。

请考虑/employeese/{id}endpoint的JSON响应:

{
    "id": "123",
    "id_to_name": {
        "123" : "John Doe"
    },
    "id_to_age": {
        "123" : 30
    }
}

使用Retrofit和RxJava,如何将其反序列化为一个Employee对象,该对象具有NameAge字段?

有更好的办法吗?

共有1个答案

潘向明
2023-03-14

完整的解决方案似乎很多,但这将允许您使用Employee而不是EmployeeResponse编写改型接口。以下是游戏计划:

  • 您仍然需要EmployeeResponseEmployee对象,其中EmployeeResponse正好映射到从API获得的内容。将响应视为Employee的构建器,并编写一个静态工厂方法,该方法从Employee返回Employee,即。employee=employee.newinstance(响应);
  • 您将为GSON创建自定义的TypeAdapterFactory。当Gson看到您请求Employee对象时,我们将让TypeAdapter实际创建EmployeeResponse,然后通过上面描述的静态工厂方法返回Employee

您的TypeAdapterFactory将如下所示:

public class EmployeeAdapterFactory implements TypeAdapterFactory {
  @Override public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
    return type.getRawType() == Employee.class
           ? (TypeAdapter<T>) employeeAdapter(gson, (TypeToken<Employee>) type)
           : null;
  }

  private TypeAdapter<Employee> employeeAdapter(Gson gson, TypeToken<Employee> type) {
    return new TypeAdapter<Employee>() {
      @Override public void write(JsonWriter out, Employee value) throws IOException {
        // TODO serialization logic to go from an Employee back to EmployeeResponse structure, if necessary
      }

      @Override public Employee read(JsonReader in) throws IOException {
        return Employee.newInstance(gson.fromJson(in, EmployeeResponse.class));
      }
    };
  }
}
Gson gson = new GsonBuilder()
    .registerTypeAdapterFactory(new EmployeeAdapterFactory())
    .build();

Retrofit retrofit = new Retrofit.Builder().baseUrl("https://foo.bar")
    .addConverterFactory(GsonConverterFactory.create(gson))
    ... // your other Retrofit configs, like RxJava call adapter factory
    .build();
 类似资料:
  • 我有一个JSON,它带有一个包含任意键和值类型的标记,我想将其读入Java中POJO内的映射。映射将是指向JsonValue或JsonNode之类的字符串。我正在使用对象映射器解析json。 有人对如何设置我的POJO来与杰克逊一起完成这一任务有什么建议吗?还是一种更好的方式? Json示例: 映射方法: 我的POJO:

  • 问题内容: 我们有一张有很多列的大桌子。移至MySQL Cluster后,由于以下原因无法创建表: 错误1118(42000):行大小太大。不包括BLOB在内的已使用表类型的最大行大小为14000。这包括存储开销,请查阅手册。您必须将某些列更改为TEXT或BLOB 举个例子: 这是用于存储配置参数的表。我在想,我们可以将一些列合并为一个列,并将其存储为JSON对象,然后将其转换为Java对象。 例

  • 我们有一张有很多柱子的大桌子。在我们移动到MySQL集群后,表无法创建,因为: 错误1118 (42000):行大小过大。使用的表类型(不包括BLOB)的最大行大小为14000。这包括存储开销,检查手册。您必须将一些列更改为TEXT或BLOB 例如: 它是一个用于存储配置参数的表。我在想,我们可以将一些列组合成一个列,并将其存储为JSON对象,并将其转换为Java对象。 例如: 我们定义了: 通过

  • 问题内容: 我有一个问题。我想使用JAXB将一个对象转换为另一个对象。就像在中,我有一个class 和另一个class ,它们都有相同的参数,实际上都是相同的(复制粘贴),但是包不同。我想使用进行它们之间的转换。 怎么做,请帮帮我。 问题答案: 您可以执行以下操作。 注意: 不需要利用JAXBSource将数据具体化为XML。 它在对象模型上不需要任何注释。 com.home.Student co

  • 我有一个有内部地图的POJO。我想将它从JSON反序列化为HashMap,但Jackson将JSON的内部映射反序列化为LinkedHashMap。我可以通过将映射的类型从“Map”更改为“HashMap”来强制它使用HashMap,但我想知道是否有方法告诉Jackson将反序列化为Map的特定实现? 这里是JSON: 和转换类: 如何使用ObjectMapper:

  • 如何将jackson JSON映射器与Java 8 LocalDateTime一起使用? JSONMappingException:无法从JSON字符串实例化类型[simple type,class java.time.LocalDateTime]的值;没有单字符串构造函数/工厂方法(通过引用链:mydto[“field1”]->subdto[“date”])