当前位置: 首页 > 知识库问答 >
问题:

如何使用GSON将空字符串视为空对象?

丁韬
2023-03-14

我正在从Reddit API检索评论。该模型是线程化的,这样每个评论都可以在内部有一个评论列表,名为回复。下面是一个JSON响应的示例:

[
   {
      "kind":"Listing",
      "data":{
         "children":[
            {
               "data":{
                  "body":"comment",
                  "replies":{
                     "kind":"Listing",
                     "data":{
                        "children":[
                           {
                              "data":{
                                 "body":"reply to comment",
                                 "replies":""
                              }
                           }
                        ]
                     }
                  }
               }
            }
         ]
      }
   }
]

这是我如何用POJO建模的。上面的回复将被视为评论列表。

public class CommentListing {
    @SerializedName("data")
    private CommentListingData data;
}

public final class CommentListingData {
    @SerializedName("children")
    private List<Comment> comments;
}

public class Comment {
    @SerializedName("data")
    private CommentData data;
}

public class CommentData {
    @SerializedName("body")
    private String body;

    @SerializedName("replies")
    private CommentListing replies;
}

请注意底层CommentData POJO如何引用另一个名为“回复”的CommentList。

这个模型一直工作到GSON到达最后一个没有回复的子CommentData。API提供的不是空字符串,而是空字符串。自然,这会导致GSON异常,即它需要一个对象,但找到一个字符串:

"replies":""

应为BEGIN_对象,但为字符串

我试图在CommentData类上创建一个自定义反序列化器,但由于模型的递归性质,它似乎没有到达模型的底层。我想这是因为我正在使用一个单独的GSON实例来完成反序列化。

@Singleton
@Provides
Gson provideGson() {
    Gson gson = new Gson();
    return new GsonBuilder()
            .registerTypeAdapter(CommentData.class, new JsonDeserializer<CommentData>() {
                @Override
                public CommentData deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
                    JsonObject commentDataJsonObj = json.getAsJsonObject();
                    JsonElement repliesJsonObj = commentDataJsonObj.get("replies");
                    if (repliesJsonObj != null && repliesJsonObj.isJsonPrimitive()) {
                        commentDataJsonObj.remove("replies");
                    }

                    return gson.fromJson(commentDataJsonObj, CommentData.class);
                }
            })
            .serializeNulls()
            .create();
}

如何强制GSON返回null而不是String,以便它不会尝试将String强制输入我的POJO?或者如果这不可能,请手动协调数据问题?如果您需要其他上下文或信息,请告诉我。谢谢。

共有1个答案

邹杰
2023-03-14

总体而言,您的代码看起来不错,但我建议您做几件事:

  • 您的类型适配器不应该从外部捕获Gson实例。类型适配器工厂TypeAdapterFactory)就是为此而设计的。此外,在JSON序列化程序和反序列化程序中,您可以分别通过JsonSerializationContextJsonDeserializationContext隐式引用它(这在某些情况下避免了无限递归)
public final class EmptyStringAsNullTypeAdapter<T>
        implements JsonDeserializer<T> {

    // Let Gson instantiate it itself
    private EmptyStringAsNullTypeAdapter() {
    }

    @Override
    public T deserialize(final JsonElement jsonElement, final Type type, final JsonDeserializationContext context)
            throws JsonParseException {
        if ( jsonElement.isJsonPrimitive() ) {
            final JsonPrimitive jsonPrimitive = jsonElement.getAsJsonPrimitive();
            if ( jsonPrimitive.isString() && jsonPrimitive.getAsString().isEmpty() ) {
                return null;
            }
        }
        return context.deserialize(jsonElement, type);
    }

}

然后只需注释回复字段:

@SerializedName("replies")
@JsonAdapter(EmptyStringAsNullTypeAdapter.class)
private CommentListing replies;
 类似资料:
  • 我使用gson序列化java对象到json。 这个生成器处理好的空值。但与此同时,我希望它处理空字符串也为空。 这怎么能做到呢?

  • 问题内容: 我使用google-gson将Java映射序列化为JSON字符串。它提供了一个生成器来处理null值: 问题在于结果是字符串,如: 所需的结果是: 我可以为和进行字符串替换,但这很难看并且容易出错。是否有本地gson支持添加自定义String而不是? 问题答案: 如果这是您的应用程序类型,则可以注册类型适配器。但是Gson不允许您更改字符串或原始类型的序列化形式。 最好的选择是更改Ja

  • 问题内容: 我已经编写了一个android程序来将值从Web服务加载到表行。但是值变为null,因此我需要将其转换为字符串。有人可以告诉我这样做的方法吗? 现在从Web服务获取空值,因此我需要将其转换为string 。 LogCat: 问题答案: 用这个,

  • 问题内容: 我有以下类,它是由Jackson映射的(简化版): 在某些情况下,服务器会返回,然后我想将name设置为空的Java String。 是否有任何Jackson注释,或者如果属性为,我应该只检查getter中的null并返回空字符串? 问题答案: 您可以在默认构造函数中或声明时进行设置: 要么

  • 我有以下由Jackson映射的类(简化版): 在某些情况下,服务器返回,然后我想将name设置为空Java字符串。 是否有任何Jackson注释,或者如果属性为,我应该只检查getter中的null并返回空字符串吗?

  • 我正在尝试从json转换为Java对象。我收到一个json字符串,其中包括一个书籍列表: 我创建了一个名为Books的对象: 另外,我正在使用doGet方法从RESTful webservice中以以下方式检索这些数据: 干杯