Analisador de resposta Json para matriz ou objeto

Estou escrevendo uma biblioteca para consumir uma API Json e estou enfrentando um problema de design ao usar o Gson como a biblioteca de análise.

Um dos pontos de extremidade retorna umarray de objetos se tudo correr bem assim:

[
  { 
   "name": "John",
   "age" : 21
  },
  { 
   "name": "Sarah",
   "age" : 32
  },
]

No entanto, o esquema de erro para todos os terminais na API é um jsonobject em vez de uma matriz.

{
  "errors": [
     { 
       "code": 1001,
       "message": "Something blew up"
     }
  ]
}

O problema surge ao modelar isso em POJOs. Como o esquema de erro é comum a todos os pontos de extremidade da API, decidi ter um resumoApiResponse classe que mapeará apenas o atributo de erros

public abstract class ApiResponse{

  @SerializedName("errors")
  List<ApiResponseError> errors;
}

public class ApiResponseError {

  @SerializedName("code")
  public Integer code;

  @SerializedName("message")
  public String message;
} 

Agora eu gostaria de herdar deApiResponse ter o mapeamento de erro "de graça" e uma resposta de POJO por terminal da API. No entanto, o objeto json de nível superior para esta resposta é uma matriz (se o servidor conseguir executar a solicitação), portanto, não posso criar uma nova classe para mapeá-la como gostaria.

Eu decidi ainda criar uma classe estendendoApiResponse:

public class ApiResponsePerson extends ApiResponse {

  List<Person> persons;
}

E implementou um desserializador personalizado para analisar corretamente o json, dependendo do tipo do objeto de nível superior e configurá-lo para o campo correto na seguinte classe:

public class DeserializerApiResponsePerson implements JsonDeserializer<ApiResponsePerson> {

  @Override 
  public ApiResponse deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {

    ApiResponsePerson response = new ApiResponsePerson();
    if (json.isJsonArray()) {
      Type personType = new TypeToken<List<Person>>() {}.getType();
      response.persons = context.deserialize(json, personType);
      return response;
    }
    if (json.isJsonObject()) {
      JsonElement errorJson = json.getAsJsonObject().get("errors");
      Type errorsType = new TypeToken<List<ApiResponseError>>() {}.getType();
      response.errors = context.deserialize(errorJson, errorsType);
      return response;
    }
    throw new JsonParseException("Unexpected Json for 'ApiResponse'");
  }
}

Que eu adicionarei ao Gson

Gson gson = new GsonBuilder()
    .registerTypeAdapter(ApiResponsePerson.class, new DeserializerApiResponsePerson())
    .create();

Existe alguma maneira de modelar esses POJOs e fazer com que o Gson reconheça essa estrutura sem precisar lidar manualmente com esse cenário? Existe alguma maneira melhor de conseguir isso? Estou perdendo algum cenário em que o desserializador pode falhar ou não funcionar conforme o esperado?

obrigado

questionAnswers(3)

yourAnswerToTheQuestion