我正在使用一个api,其中一个特定字段(下面)通常包含一个字符串数组。但是,如果数组为空,则api在通常为字符串数组的形式中返回一个空对象。这是引起问题的领域。
正常。
"a": [
"str"
]
空。
"a": [
{}
]
第二种情况导致Gson崩溃,并抛出JsonSyntaxException。我该如何处理?
答案 0 :(得分:1)
让我们假设您有一个表示API响应的类,例如:
public class Response {
private String[] a;
private String b;
private String c;
}
获取Response
对象的一种方法来解析a
的JSON是否有效是创建JsonDeserializer
来检查a
是否可以解析并排除解析的一种方法。 a
如果失败,则将a
留给null
。
public class SkipBadSyntaxDeserializer implements JsonDeserializer<Response> {
// This strategy is used if parse of field a fails
private final ExclusionStrategy excludeA = new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes f) {
return "a".equals(f.getName());
}
// no need to care of this used only here for the Response class
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}
};
// one parser for good and another for bad format
private final Gson gson = new Gson(),
gsonBadFormat = new GsonBuilder()
.addDeserializationExclusionStrategy(excludeA).create();;
@Override
public Response deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context)
throws JsonParseException {
try {
return gson.fromJson(json, Response.class);
} catch (JsonSyntaxException e) {
// parse a failed try again without it
return gsonBadFormat.fromJson(json, Response.class);
}
}
}
尝试:
new GsonBuilder().registerTypeAdapter(Response.class,
new SkipBadSyntaxDeserializer())
.create()
.fromJson(JSON, Response.class);
如果JSON是这样的:
{
"a": [{}],
"b": "bval",
"c": "cval"
}
然后Response
的属性为:
a=null
b="bval"
c="cval"
根据您自己的答案:如果可以更改DTO进行响应,则使用注释@JsonAdapter
将使您可以按字段处理此问题。反序列化器将很简单:
public class SkipExceptionAdapter implements JsonDeserializer<String[]> {
@Override
public String[] deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context)
throws JsonParseException {
try {
return context.deserialize(json, String[].class);
} catch (JsonSyntaxException e) {
return new String[] {}; // or null how you wish
}
}
}
和Response.a
@JsonAdapter(SkipExceptionAdapter.class)
private String[] a;
将仅针对该字段进行处理。
答案 1 :(得分:1)
我不知道这是否是最好的方法,但是它可以工作。
可以使用@JsonAdapter(MyTypeAdapter.class)注释错误字段。然后,TypeAdapter可以使用其read方法并使用peek()weather检查下一个值是否不是预期的类型。