I have an API response that looks like this:
{
"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",
...
}
}
I'm trying to get at what is in the attribute_name_that_i_know that has arbitrary keys (length and name.)
When I put:
@SerializedName("attribute_name_that_i_know")
Sometype sometype;
in the parent object's class sometype (the nested object) is always null. I can't figure out how to just drop the nested data into an object. Any object, I don't care. I just want gson to keep the data.
Having that field Object is not your only choice here. I wouldn't call it an anti-pattern because you cannot do much where you can't have enough type info. Since you expect arbitrary data structure, you can accomplish what you need or smooth it with:
Map<String, Object> - This is already a deserialized value. The pro for this approach is that it can hide unknown objects one level down having the keys known at the top-most level. Some disadvantages are that deserialization may be expensive for some strategies, and that the underlying Objects can be deserialized as raw primitive literals (like strings, numbers, and that's fine) and more complex raw structures like maps (Map<String, Object>) and lists (List<Object>) because Gson does not have enough information to restore a ready-to-use object from any given JSON until you can provide an exact mapping.JsonObject - Another option that can be useful. Some pros for this option is that you can introspect the structure of unknown arbirtrary objects more precisely and even deserialize some fields in a certain way you want, because Gson does not make deserialization here per se (in terms of your application scope), but constructs a JSON object tree here that you can traverse with easy to use Gson tree API (yes, you can get rid of instanceof comparing to the first option, but you "instanceof"-like introspection is still necessary). A con is that you should have DTO (well-Gson-aware) and your application objects (that know nothing of Gson at all) thus only letting Gson-aware classes to live in the scope of the application-to-service-talk layer.
JsonElement - An alternative of the latter option for cases you expect that arbitrary property to be a primitive, an array, or null (the latter does not play much here). Looks like Object but still has more convenient introspection facilities and keeps the structure in the tree form.JsonDeserializer<T> - The most advanced option. If you can make some analysis of the arbitrary object based on the JSON tree structure in order to restore the right type, then you can try to write such a deserializer. Unfortunately, your mapping type would be still Object, but you could create a concrete object you need if it's possible. JsonDeserializers can be attached to Gson via GsonBuilder.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With