Предположим, у вас есть класс, представляющий ответ API, например:
public class Response {
private String[] a;
private String b;
private String c;
}
Один из способов получить объект Response
, который был проанализирован, является ли JSON для a
действительным или нет, это создать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;
будет обрабатывать его только для этого поля.