oi Victor, entendi o problema, é justamente no objeto que está usando para realizar a conversão.
Repare que os campos que estão vindo no JSON são diferentes dos atributos que está marcando. Por padrão o Jackson quebra a App caso tenha algum campo que ele não consiga realizar o parse.
Evitando a falha para campos desconhecidos em uma classe específica
Para evitar esse erro, você pode realizar duas configurações, a primeira delas é anotar a classe que está sendo convertida com @JsonIgnoreProperties(ignoreUnknown = true)
, em código ficaria algo assim:
@JsonIgnoreProperties(ignoreUnknown = true)
public class RepositorioDTO {
private List<Repositorio> repositorios;
public List<Repositorio> getRepositorios() {
return repositorios;
}
}
Então, dessa forma, mesmo que não exista o campo que está no Jackson, a sua App não vai quebrar ao tentar converter essa classe. Porém, repare que você vai ter que configurar todas as classes desse jeito caso não queira esse comportamento...
Evitando a falha para campos desconhecidos em todas as classes por padrão
Para evitar essa config em todas as classes, você pode realizar essa config direto na criação do Retrofit:
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(JacksonConverterFactory.create(mapper))
.client(client.build())
.build();
A classe ObjectMapper
é justamente a classe que representar o serializador e deserializador do Jackson, a chamada do método configure()
enviando o paramêtro DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
significa que está sendo feita a configuração de falha para casos que venham campos desconhecidos (como é o caso de agora), então o parâmetro false
, indica que esse comportamento não é desejado.
Por fim, basta apenas enviar o mapper
dentro do create()
do JacksonConverterFactory
que todas as classes que forem convertidas por meio do Retrofit usando o Jackson, vão ter esse comportamento por padrão. Portanto, não precisa usar aquela annotation após aplicar essa configuração.
Indicando o campo esperado para um atributo
Agora, o único detalhe que precisa se atentar é no nome dos atributos, por exemplo, suponhamos que queira pegar o campo total_count
do JSON que está vindo da API. Esse atributo seria do DTO, certo? A princípio faríamos algo do gênero considerando a tradução do parâmetro:
public class RepositorioDTO {
private int contagemTotal;
public int getContagemTotal() {
return totalCount;
}
private List<Repositorio> repositorios;
public List<Repositorio> getRepositorios() {
return repositorios;
}
}
Entretanto, repare que o Jackson não vai conseguir realizar o processo de bind entre o campo total_count
e o contagemTotal
, pois os nomes não batem! Mas é algo desejado por nós manter o valor nesse atributo, certo? Para isso, você pode usar a annotation @JsonProperty
e enviar o campo que espera para esse atributo da seguinte maneira:
public class RepositorioDTO {
@JsonProperty("total_count")
private int contagemTotal;
public int getContagemTotal() {
return contagemTotal;
}
private List<Repositorio> repositorios;
public List<Repositorio> getRepositorios() {
return repositorios;
}
}
Pronto! Dessa maneira o bind ocorre sem nenhum problema. Claro, infelizemente vai precisar fazer isso em todos os campos para casar o bind... Lembrando que se um campo não vier com o valor esperado, provalmente foi um problema de estrutura da classe que foi implementada.
Se tiver alguma dúvida é só avisar.
[]s