{"id":7974,"date":"2015-11-14T08:40:23","date_gmt":"2015-11-14T08:40:23","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2015\/11\/14\/get-nested-json-object-with-gson-using-retrofit-open-source-projects-square-retrofit\/"},"modified":"2015-11-14T08:40:23","modified_gmt":"2015-11-14T08:40:23","slug":"get-nested-json-object-with-gson-using-retrofit-open-source-projects-square-retrofit","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2015\/11\/14\/get-nested-json-object-with-gson-using-retrofit-open-source-projects-square-retrofit\/","title":{"rendered":"Get nested JSON object with GSON using retrofit-open source projects square\/retrofit"},"content":{"rendered":"<p>@BrianRoach&#8217;s solution is the correct solution. It is worth noting that in the special case where you have nested custom objects that both need a custom <code>TypeAdapter<\/code>, you must register the <code>TypeAdapter<\/code> with the <strong>new instance of GSON<\/strong>, otherwise the second <code>TypeAdapter<\/code> will never be called. This is because we are creating a new <code>Gson<\/code> instance inside our custom deserializer.<\/p>\n<p>For example, if you had the following json:<\/p>\n<pre><code>{\n    \"status\": \"OK\",\n    \"reason\": \"some reason\",\n    \"content\": {\n        \"foo\": 123,\n        \"bar\": \"some value\",\n        \"subcontent\": {\n            \"useless\": \"field\",\n            \"data\": {\n                \"baz\": \"values\"\n            }\n        }\n    }\n}\n<\/code><\/pre>\n<p>And you wanted this JSON to be mapped to the following objects:<\/p>\n<pre><code>class MainContent\n{\n    public int foo;\n    public String bar;\n    public SubContent subcontent;\n}\n\nclass SubContent\n{\n    public String baz;\n}\n<\/code><\/pre>\n<p>You would need to register the <code>SubContent<\/code>&#8216;s <code>TypeAdapter<\/code>. To be more robust, you could do the following:<\/p>\n<pre><code>public class MyDeserializer implements JsonDeserializer {\n    private final Class mNestedClazz;\n    private final Object mNestedDeserializer;\n\n    public MyDeserializer(Class nestedClazz, Object nestedDeserializer) {\n        mNestedClazz = nestedClazz;\n        mNestedDeserializer = nestedDeserializer;\n    }\n\n    @Override\n    public T deserialize(JsonElement je, Type type, JsonDeserializationContext jdc) throws JsonParseException {\n        \/\/ Get the \"content\" element from the parsed JSON\n        JsonElement content = je.getAsJsonObject().get(\"content\");\n\n        \/\/ Deserialize it. You use a new instance of Gson to avoid infinite recursion\n        \/\/ to this deserializer\n        GsonBuilder builder = new GsonBuilder();\n        if (mNestedClazz != null &amp;&amp; mNestedDeserializer != null) {\n            builder.registerTypeAdapter(mNestedClazz, mNestedDeserializer);\n        }\n        return builder.create().fromJson(content, type);\n\n    }\n}\n<\/code><\/pre>\n<p>and then create it like so:<\/p>\n<pre><code>MyDeserializer myDeserializer = new MyDeserializer(SubContent.class,\n                    new SubContentDeserializer());\nGson gson = new GsonBuilder().registerTypeAdapter(Content.class, myDeserializer).create();\n<\/code><\/pre>\n<p>This could easily be used for the nested &#8220;content&#8221; case as well by simply passing in a new instance of <code>MyDeserializer<\/code> with null values.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>@BrianRoach&#8217;s solution is the correct solution. It is worth noting that in the special case where you have nested custom objects that both need a custom TypeAdapter, you must register the TypeAdapter with the new instance of GSON, otherwise the second TypeAdapter will never be called. This is because we are creating a new Gson [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-7974","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/7974","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=7974"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/7974\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=7974"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=7974"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=7974"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}