Let us assume you have a class representing the API response, like:
public class Response {
private String[] a;
private String b;
private String c;
}
One way to get the Response object parsed whether JSON for a is valid or not is to create a JsonDeserializer that checks if a can parsed and excludes parsing of a if it fails, so leaves a to 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);
}
}
}
Try it with:
new GsonBuilder().registerTypeAdapter(Response.class,
new SkipBadSyntaxDeserializer())
.create()
.fromJson(JSON, Response.class);
If JSON would be like:
{
"a": [{}],
"b": "bval",
"c": "cval"
}
then properties for Response would be:
a=null
b="bval"
c="cval"
Update
Based on your own answer: if it is possible to alter DTO for response then using annotation @JsonAdapter will let you to handle this per field. Deserializer will then be simply:
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
}
}
}
and annotation in Response.a
@JsonAdapter(SkipExceptionAdapter.class)
private String[] a;
will handle it for that field only.