我有一个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保存数据。
答案 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);
}
这似乎是一种反模式,但它有效。如果有人有更好的解决方案,我会选择这个功能性但难看的解决方案。