Ste*_*eve 3 java json reddit gson
我正在从Reddit API中检索评论.该模型具有线程,以便每个注释可以在内部具有注释列表,命名为回复.以下是JSON响应的外观示例:
[
{
"kind":"Listing",
"data":{
"children":[
{
"data":{
"body":"comment",
"replies":{
"kind":"Listing",
"data":{
"children":[
{
"data":{
"body":"reply to comment",
"replies":""
}
}
]
}
}
}
}
]
}
}
]
Run Code Online (Sandbox Code Playgroud)
以下是我使用POJO进行建模的方法.上述响应将被视为CommentListings列表.
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;
}
Run Code Online (Sandbox Code Playgroud)
注意底层CommentData POJO如何引用另一个名为"replies"的CommentList.
此模型有效,直到GSON到达最后一个没有回复的子CommentData.API不提供null,而是提供空字符串.当然,这会导致GSON异常,它需要一个对象但却找到一个String:
"replies":""
Run Code Online (Sandbox Code Playgroud)
预计BEGIN_OBJECT但是STRING
我试图在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();
}
Run Code Online (Sandbox Code Playgroud)
如何强制GSON返回null而不是String,以便它不会尝试强制String进入我的POJO?或者,如果不可能,手动协调数据问题?如果您需要其他背景信息,请与我们联系.谢谢.
一般来说你的代码看起来不错,但我会推荐一些东西:
Gson从外部捕获实例.类型适配器工厂(TypeAdapterFactory)是为此目的而设计的.此外,在JSON序列化和反序列化,你可以通过隐指之JsonSerializationContext和JsonDeserializationContext分别为(这避免了在某些情况下无限递归).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);
}
}
Run Code Online (Sandbox Code Playgroud)
然后只需注释该replies字段:
@SerializedName("replies")
@JsonAdapter(EmptyStringAsNullTypeAdapter.class)
private CommentListing replies;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2366 次 |
| 最近记录: |