title: How do I treat empty Strings as null objects with GSON?
body: <p>I'm retrieving comments from the Reddit API. The model is threaded such that each Comment can internally have a List of Comments, named <strong>replies</strong>. Here's an example of how a JSON response would look:</p>
  
  <pre><code>[
     {
        "kind":"Listing",
        "data":{
           "children":[
              {
                 "data":{
                    "body":"comment",
                    "replies":{
                       "kind":"Listing",
                       "data":{
                          "children":[
                             {
                                "data":{
                                   "body":"reply to comment",
                                   "replies":""
                                }
                             }
                          ]
                       }
                    }
                 }
              }
           ]
        }
     }
  ]
  </code></pre>
  
  <p>Here is how I model this with POJOs. The response above would be considered a List of CommentListings.</p>
  
  <pre><code>public class CommentListing {
      @SerializedName("data")
      private CommentListingData data;
  }
  
  public final class CommentListingData {
      @SerializedName("children")
      private List&lt;Comment&gt; comments;
  }
  
  public class Comment {
      @SerializedName("data")
      private CommentData data;
  }
  
  public class CommentData {
      @SerializedName("body")
      private String body;
  
      @SerializedName("replies")
      private CommentListing replies;
  }
  </code></pre>
  
  <p>Note how the bottom level CommentData POJO refers to another CommentListing called "replies".</p>
  
  <p>This model works until GSON reaches the last child CommentData where there are no replies. Rather than providing a null, the API is providing an empty String. Naturally, this causes a GSON exception where it expects an object but finds a String: </p>
  
  <pre><code>"replies":""
  </code></pre>
  
  <p><strong><em>Expected BEGIN_OBJECT but was STRING</em></strong></p>
  
  <p>I attempted to create a custom deserializer on the CommentData class, but due to the recursive nature of the model it seems not to reach the bottom levels of the model. I imagine this is because I'm using a separate GSON instance to complete deserialization.</p>
  
  <pre><code>@Singleton
  @Provides
  Gson provideGson() {
      Gson gson = new Gson();
      return new GsonBuilder()
              .registerTypeAdapter(CommentData.class, new JsonDeserializer&lt;CommentData&gt;() {
                  @Override
                  public CommentData deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
                      JsonObject commentDataJsonObj = json.getAsJsonObject();
                      JsonElement repliesJsonObj = commentDataJsonObj.get("replies");
                      if (repliesJsonObj != null &amp;&amp; repliesJsonObj.isJsonPrimitive()) {
                          commentDataJsonObj.remove("replies");
                      }
  
                      return gson.fromJson(commentDataJsonObj, CommentData.class);
                  }
              })
              .serializeNulls()
              .create();
  }
  </code></pre>
  
  <p>How can I force GSON to return a null instead of a String so that it doesn't try to force a String into my POJO? Or if that's not possible, manually reconcile the data issue? Please let me know if you need additional context or information. Thanks.</p>