如果 json 字段类型动态更改,如何使用改造处理 json 响应
How to handle json response using retrofit if json field type changed dynamically
我正在使用改造 2 进行解析 api。
对于某些响应,它已成功完成,但对于某些响应,它会停止并显示错误
com.google.gson.JsonSyntaxException: java.lang.NumberFormatException:
Invalid double: ""
解析成功的响应是:
{
"post_list": [{
"like_count": "1",
"like_id": 47,
"like_user_id": 24,
"like_full_name": "Zika zika",
"like_full_image": "http:\/\/graph.facebook.com\/123456789\/picture?type=large",
"comment_count": 7,
"comment_id": 235,
"comment_text": "Xhhc",
"comment_user_id": 22,
"comment_full_name": "Azz Sha",
"comment_full_image": "http:\/\/demo.net\/apps\/demo\/web\/img\/uploads\/abc.jpg"
}],
"is_last": "N",
"code": 200,
"status": "Success"
}
失败的是:
{
"post_list": [{
"like_count": "0",
"like_id": "",
"like_text": "",
"like_user_id": "",
"like_full_name": "",
"like_full_image": "",
"comment_count": 0,
"comment_id": "",
"comment_text": "",
"comment_user_id": "",
"comment_full_name": "",
"comment_full_image": ""
}],
"is_last": "N",
"code": 200,
"status": "Success"
}
和 PostList class:
@SerializedName("like_count")
private String likeCount;
@SerializedName("like_id")
private Integer likeId;
@SerializedName("like_user_id")
private Integer likeUserId;
@SerializedName("like_full_name")
private String likeText;
@SerializedName("like_text")
private String likeFullName;
@SerializedName("like_full_image")
private String likeFullImage;
@SerializedName("comment_count")
private Integer commentCount;
@SerializedName("comment_id")
private String commentId;
@SerializedName("comment_text")
private String commentText;
@SerializedName("comment_user_id")
private String commentUserId;
@SerializedName("comment_full_name")
private String commentFullName;
@SerializedName("comment_full_image")
private String commentFullImage;
//getter setters
我不太了解改造,但我尝试使用这个 class 作为反序列化器,参考 this 但仍然没有成功。
public class TimelineDeserializer implements JsonDeserializer<PostList> {
@Override
public PostList deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
Gson gson = new Gson();
PostList postList=gson.fromJson(json, PostList.class);
final JsonObject jsonObject = json.getAsJsonObject();
if(postList.getLikeCount().equals("0")){
final int likeId=jsonObject.get("like_id").getAsInt();
final int likeUserID=jsonObject.get("like_user_id").getAsInt();
postList.setLikeId(likeId);
postList.setLikeUserId(likeUserID);
}
return postList;
}
}
用于初始化改造:
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(PostList.class, new TimelineDeserializer());
Gson gson = new GsonBuilder()
.setLenient()
.create();
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
retrofit = new Retrofit.Builder().baseUrl(BASE_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create(gson)).build();
我正在日志中获取响应正文,但遇到了 onFailure 方法。
不知道如何做到这一点。可以做任何事情而不是在后端更改它吗?帮忙欣赏一下!
您似乎将likeUserId
和likeUserId
定义为Integer
。但是,在 JSON、like_id
和 like_user_id
中是 ""
,即 String
而不是 Integer
。
而不是使用此 ("").. 您也可以使用 likeUserId=null
并在获取值之前.. 检查空值..
在得到评论员的帮助后,我发现这种响应无法用这种使用反射赋值的库处理。
因为服务器可能提供无效的json,它实际上是无效的json,因为服务器正在破坏自己的模式。它可能 以某种方式 完成,但这不是一个好的目标。
所以,我最终使用了另一个库来解析这个响应。
我正在使用改造 2 进行解析 api。 对于某些响应,它已成功完成,但对于某些响应,它会停止并显示错误
com.google.gson.JsonSyntaxException: java.lang.NumberFormatException: Invalid double: ""
解析成功的响应是:
{
"post_list": [{
"like_count": "1",
"like_id": 47,
"like_user_id": 24,
"like_full_name": "Zika zika",
"like_full_image": "http:\/\/graph.facebook.com\/123456789\/picture?type=large",
"comment_count": 7,
"comment_id": 235,
"comment_text": "Xhhc",
"comment_user_id": 22,
"comment_full_name": "Azz Sha",
"comment_full_image": "http:\/\/demo.net\/apps\/demo\/web\/img\/uploads\/abc.jpg"
}],
"is_last": "N",
"code": 200,
"status": "Success"
}
失败的是:
{
"post_list": [{
"like_count": "0",
"like_id": "",
"like_text": "",
"like_user_id": "",
"like_full_name": "",
"like_full_image": "",
"comment_count": 0,
"comment_id": "",
"comment_text": "",
"comment_user_id": "",
"comment_full_name": "",
"comment_full_image": ""
}],
"is_last": "N",
"code": 200,
"status": "Success"
}
和 PostList class:
@SerializedName("like_count")
private String likeCount;
@SerializedName("like_id")
private Integer likeId;
@SerializedName("like_user_id")
private Integer likeUserId;
@SerializedName("like_full_name")
private String likeText;
@SerializedName("like_text")
private String likeFullName;
@SerializedName("like_full_image")
private String likeFullImage;
@SerializedName("comment_count")
private Integer commentCount;
@SerializedName("comment_id")
private String commentId;
@SerializedName("comment_text")
private String commentText;
@SerializedName("comment_user_id")
private String commentUserId;
@SerializedName("comment_full_name")
private String commentFullName;
@SerializedName("comment_full_image")
private String commentFullImage;
//getter setters
我不太了解改造,但我尝试使用这个 class 作为反序列化器,参考 this 但仍然没有成功。
public class TimelineDeserializer implements JsonDeserializer<PostList> {
@Override
public PostList deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
Gson gson = new Gson();
PostList postList=gson.fromJson(json, PostList.class);
final JsonObject jsonObject = json.getAsJsonObject();
if(postList.getLikeCount().equals("0")){
final int likeId=jsonObject.get("like_id").getAsInt();
final int likeUserID=jsonObject.get("like_user_id").getAsInt();
postList.setLikeId(likeId);
postList.setLikeUserId(likeUserID);
}
return postList;
}
}
用于初始化改造:
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(PostList.class, new TimelineDeserializer());
Gson gson = new GsonBuilder()
.setLenient()
.create();
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
retrofit = new Retrofit.Builder().baseUrl(BASE_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create(gson)).build();
我正在日志中获取响应正文,但遇到了 onFailure 方法。 不知道如何做到这一点。可以做任何事情而不是在后端更改它吗?帮忙欣赏一下!
您似乎将likeUserId
和likeUserId
定义为Integer
。但是,在 JSON、like_id
和 like_user_id
中是 ""
,即 String
而不是 Integer
。
而不是使用此 ("").. 您也可以使用 likeUserId=null
并在获取值之前.. 检查空值..
在得到评论员的帮助后,我发现这种响应无法用这种使用反射赋值的库处理。
因为服务器可能提供无效的json,它实际上是无效的json,因为服务器正在破坏自己的模式。它可能 以某种方式 完成,但这不是一个好的目标。
所以,我最终使用了另一个库来解析这个响应。