3
respostas

[Dúvida] Dúvida no desafio literalura

Olá, estou empacado no desafio LiterAlura. O json que vimos nas aulas que usamos o OMDB era um json "mais simples" (ex.: { "Title": "Guardians of the Galaxy Vol. 2", "Year": "2017",...}, porém agora com o gutendex recebemos um json com quatro chaves e a que nos interessa ("results") contém os dados em uma lista. Tive facilidade para acessar o json e pegar apenas o results utilizando um record, porém não consigo interagir com autor, downloads etc.

Meu código até aqui:

private void buscarSerieWeb() {
        System.out.println("Digite o nome do livro ou autor(a):" );
        var pesquisa = leitura.nextLine();

        var json = api.obterDados(LINK + pesquisa.replace(" ", "+"));
        DadosResults resultado = converteDados.obterDados(json, DadosResults.class);
        System.out.println(resultado);
        
        //ou também
        
        System.out.println(resultado.resultados().get(0).getAutor());
    }

A função obterDados chama o objectMapper na classe converter dados. Criei um record DadosLivro que contém os parâmetros autor, titulo, downloads e idioma, e tentei converter para essa classe, mas não funcionou. Tentei também criar um objeto Livro para acessar através de uma função get, mas nada.

3 respostas

Olá Vinicius! Tudo bem?

Analisando o que você compartilhou, parece que a estrutura do JSON que você está recebendo é diferente do que você estava acostumado. No caso do Gutendex, a chave "results" contém uma lista de objetos, e é importante garantir que sua estrutura de classes em Java esteja preparada para isso.

Aqui está uma abordagem que pode ajudar:

  1. Defina uma classe para o resultado individual: Se o JSON contém informações como autor, título, downloads e idioma, você precisa de uma classe que represente cada um desses elementos. Parece que você já criou um record chamado DadosLivro, o que é ótimo.

  2. Defina uma classe para a resposta completa: Você também precisa de uma classe que represente a resposta completa da API, que contém a lista de DadosLivro. Vamos supor que você já tenha feito isso com a classe DadosResults.

Aqui está um exemplo de como essas classes podem ser definidas:

// Classe para um único livro
public record DadosLivro(String autor, String titulo, int downloads, String idioma) {}

// Classe para a resposta completa
public record DadosResults(List<DadosLivro> resultados) {}
  1. Certifique-se de que o mapeamento está correto: Quando você chama converteDados.obterDados(json, DadosResults.class);, o método obterDados precisa estar configurado para mapear corretamente o JSON para essas classes. Certifique-se de que o ObjectMapper está configurado corretamente para lidar com record.

  2. Acesse os dados: Depois de garantir que o JSON está sendo mapeado corretamente, você deve conseguir acessar os dados da seguinte forma:

System.out.println(resultado.resultados().get(0).autor());

Se você ainda estiver enfrentando problemas, verifique se os nomes das chaves no JSON correspondem exatamente aos nomes dos campos em seus record. O ObjectMapper é sensível a maiúsculas e minúsculas, então qualquer diferença pode causar problemas.

Espero ter ajudado e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.

Acredito que eu esteja fazendo algo muito próximo do que me mostrou.

//Esses são meus records:
@JsonIgnoreProperties(ignoreUnknown = true)
public record DadosResults(@JsonAlias("results") List<Livro> resultados) {
}

@JsonIgnoreProperties(ignoreUnknown = true)
public record DadosLivro(@JsonAlias("title")String titulo,
                         @JsonAlias("authors")List<Autor> autor,
                         @JsonAlias("languages") List<String> idioma,
                         @JsonAlias("download_count")int downloads) {
}

//Classe Livro
public class Livro {
    @JsonIgnoreProperties(ignoreUnknown = true)
    private String titulo;
    private List<Autor> autor;
    private List<String> idioma;
    private int downloads;

//getters e toString omitidas

Quando tento executar o código utilizando a funçãoSystem.out.println(resultado.resultados().get(0).autor()); eu recebo o seguinte erro:

java.lang.RuntimeException: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "id" (class br.com.booksearch.booksearch.models.Livro), not marked as ignorable (4 known properties: "titulo", "autor", "idioma", "downloads"])

Eu deveria adicionar o ID ao record mesmo que não precise dele? Ele não deveria estar sendo ignorado já que coloquei a marcação @JsonIgnoreProperties(ignoreUnknown = true)?

Oi, Vinicius!

Peço perdão pela demora em retornar.

O erro indica que a propriedade "id" não está sendo ignorada, mesmo com a anotação @JsonIgnoreProperties(ignoreUnknown = true) na sua classe Livro. Isso acontece porque essa anotação está na classe, mas os atributos estão no record DadosLivro, que é quem deveria estar mapeando os campos recebidos.

Você está misturando duas abordagens: uma com record (DadosLivro) e outra com classe (Livro). E o Jackson está tentando desserializar direto para a classe Livro, mas ela não sabe o que fazer com o campo "id".

Resolva fazendo o seguinte: use apenas o record DadosLivro e remova a classe Livro. O ObjectMapper consegue desserializar diretamente os itens da lista em results para DadosLivro sem problema, desde que tudo esteja anotado corretamente.

Ajuste seu código assim:


@JsonIgnoreProperties(ignoreUnknown = true)
public record DadosResults(@JsonAlias("results") List<DadosLivro> resultados) {
}

@JsonIgnoreProperties(ignoreUnknown = true)
public record DadosLivro(
    @JsonAlias("title") String titulo,
    @JsonAlias("authors") List<Autor> autor,
    @JsonAlias("languages") List<String> idioma,
    @JsonAlias("download_count") int downloads
) {
}

Com isso, o seu trecho de código funcionará corretamente:


System.out.println(resultado.resultados().get(0).autor());

Importante: verifique se você realmente está usando DadosLivro como tipo genérico da lista em DadosResults, e se removeu completamente a classe Livro, que está causando o conflito.

Fico à disposição.