改造api中的任意属性得到json反序列化

时间:2017-01-31 03:32:38

标签: android gson

我有一个API响应,如下所示:

{
"attribute_name_that_i_know": "stuff",
"attribute_name_that_i_know": "stuff",
"attribute_name_that_i_know": "stuff",
"attribute_name_that_i_know":
{
"attribute_name_that_i_do_not_know": "stuff",
"attribute_name_that_i_do_not_know": "stuff",
"attribute_name_that_i_do_not_know": "stuff",
...
}
}

我试图了解attribute_name_that_i_know中包含任意键(长度和名称)的内容。

我放的时候:

@SerializedName("attribute_name_that_i_know")
Sometype sometype;

在父对象的类中,sometype(嵌套对象)始终为null。我无法弄清楚如何将嵌套数据放入对象中。任何对象,我都不在乎。我只想让gson保存数据。

2 个答案:

答案 0 :(得分:2)

拥有该字段Object不是您唯一的选择。我不会称之为反模式,因为你不能在没有足够类型信息的地方做很多事情。由于您期望任意数据结构,您可以完成所需的工作或使用以下内容进行平滑:

  • Map<String, Object> - 这已经是一个反序列化的值。这种方法的专业人员是,它可以隐藏未知对象,在最高级别知道密钥。一些缺点是反序列化对于某些策略来说可能是昂贵的,并且潜在的Object可以被反序列化为原始原始文字(如字符串,数字和那些很好)和更复杂的原始结构,如地图(Map<String, Object>)和列表(List<Object>),因为Gson没有足够的信息来从任何给定的JSON恢复现成的对象,直到您可以提供精确的映射。
  • JsonObject - 另一个有用的选项。这个选项的一些优点是你可以更精确地内省未知arbirtrary对象的结构,甚至以你想要的某种方式反序列化某些字段,因为Gson本身不进行反序列化(就你的应用范围而言),但是构造这里有一个JSON对象树,您可以使用易于使用的Gson树API进行遍历(是的,与第一个选项相比,您可以摆脱instanceof,但是&#34; instanceof&#34; -like introspection仍然是必要)。一个问题是,您应该拥有DTO(具有良好Gson感知能力)和您的应用程序对象(根本不知道Gson),因此只允许Gson感知类存在于应用程序到服务通信层的范围内。
    • JsonElement - 对于您希望任意属性为基元,数组或null(后者在此处不起作用)的情况的后一选项的替代方法。看起来像Object,但仍然有更方便的内省设施,并以树形式保持结构。
  • JsonDeserializer<T> - 最先进的选项。如果您可以基于JSON树结构对任意对象进行一些分析以恢复正确的类型,那么您可以尝试编写这样的反序列化器。不幸的是,您的映射类型仍然是Object,但如果可能的话,您可以创建一个您需要的具体对象。 JsonDeserializer可以通过Gson附加到GsonBuilder

答案 1 :(得分:0)

我想出的解决方案是将该属性中的任何内容分配给Object,然后在getThatAttribute()上操作数据。

所以它看起来像这样:

@SerializedName("something")
String something;
@SerializedName("something_else")
String somethingElse;
@SerializedName("something_else_else")
int somethingElseElse;
@SerializedName("nested_object")
Object nestedObject;

public ConvertedClass getNestedObject() {
    return new ConvertedClass(nestedObject);
}

这似乎是一种反模式,但它有效。如果有人有更好的解决方案,我会选择这个功能性但难看的解决方案。