Solucionado (ver solução)
Solucionado
(ver solução)
6
respostas

[Dúvida] ajuda no challenge LiterAlura

olá não consigo avançar no desafio. Preciso de ajuda se estou acessando a página da url corretamente. Já fiz o teste no postman e deu certo. Porém dá muitos erros e a Luri "disse" que pode ser a url. Por favor, poderia ver se o código está correto e a url também?

package br.com.alura.literalura.principal;

import br.com.alura.literalura.model.DadosLivros;
import br.com.alura.literalura.service.ConsumoApi;
import br.com.alura.literalura.service.ConverteDados;
import com.fasterxml.jackson.core.JsonProcessingException;

import java.util.Scanner;

public class Principal {

    private final Scanner leitura = new Scanner(System.in);

    public void exibeMenu() {
        var opcao = -1;

        while (opcao != 9) {
            var menu = """
                    *** Catálogo de livros ***
                                        
                    Escolha o número de sua opção:
                                        
                    1- Buscar livro por título
                    2- Listar livros registrados
                    3- Listar autores registrados
                    4- Listar autores vivos em um determinado ano
                    5- Listar livros em um determinado idioma
                                        
                    9 - Sair
                    """;

            System.out.println(menu);
            opcao = leitura.nextInt();
            leitura.nextLine();

            switch (opcao) {
                case 1:
                    buscarLivroTitulo();
                    break;
                case 2:
                    listarLivros();
                    break;
                case 3:
                    listarAutores();
                    break;
                case 4:
                    listarAutoresVivos();
                    break;
                case 5:
                    listarLivrosIdioma();
                    break;
                case 9:
                    System.out.println("Encerrando a aplicação!");
                    break;
                default:
                    System.out.println("Opção inválida!");
            }
        }
    }

    private void listarLivrosIdioma() {
    }

    private void listarAutoresVivos() {
    }

    private void listarAutores() {
    }

    private void listarLivros() {
    }

    private void buscarLivroTitulo() {
        System.out.print("Digite o título do livro que você deseja buscar: ");
        String titulo = leitura.nextLine().trim(); 

        ConsumoApi consumoApi = new ConsumoApi();
        String url = "https://gutendex.com/books?search=" + titulo;
        String json = consumoApi.obterDados(url);

        System.out.println(json);

        DadosLivros[] livros = consumoApi.obterDados(json, DadosLivros[].class);

        if (livros.length == 0) {
            System.out.println("Nenhum livro encontrado para a pesquisa \"" + titulo + "\".");
            return;
        }

        System.out.println("*** Lista de Livros ***");

        for (DadosLivros livro : livros) {
            System.out.println("Título: " + livro.titulo());
            System.out.println("Autor: " + livro.nomeAutor());
            System.out.println("Idioma: " + livro.idioma());
            System.out.println("Downloads: " + livro.numeroDownloads());
            System.out.println("-----------------------");
        }
    }
}
6 respostas

Olá Viviane, tudo joia?

Primeiro, a URL que você está utilizando estar correta, então o problema não está localizado nela.

E, ao obter os dados da API, você está tentando converter a resposta JSON diretamente para um array de DadosLivros. Certifique-se de que a estrutura do JSON retornado pela API está conforme o que você espera. Se a resposta JSON não estiver no formato esperado, pode causar erros na desserialização.

Se após a verificação da classe você ainda não tenha conseguido solucionar o problema, peço que compartilhe todo o seu projeto, via GitHub ou Drive do Google.

Espero ter ajudado e bons estudos!

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

olá Armando fiz algumas alterações mas, estou com problemas ainda compartilho a tela erro e meu git hub. apresentou os erros, porém enviei para o repositório com erros mesmo. obrigada

https://github.com/ViviAkhemi/3-challengeLiterAlura

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Boa tarde! Viviane.

O problema está acontecendo no seu arquivo ConsumoApi, porque, por algum acaso, toda vez que você tenta consumir a API ela retorna um código 301, então ao em vez de retornar um Json com as informações, você recebe um Json vazio.

Para resolver isso, você deve alterar seu objeto cliente para realizar o redirecionamento antes que seja feita a requisição para a API. Segue a correção:

Alterar esse trecho de código:

HttpClient client = HttpClient.newHttpClient();

Para isso:

HttpClient client = HttpClient.newBuilder()
                .followRedirects(HttpClient.Redirect.ALWAYS)
                .build();

A função obterDados ficará assim:

    public String obterDados(String endereco) {
        HttpClient client = HttpClient.newBuilder()
                .followRedirects(HttpClient.Redirect.ALWAYS)
                .build();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(endereco))
                .build();
        HttpResponse<String> response;
        try {
            response = client
                    .send(request, HttpResponse.BodyHandlers.ofString());
        } catch (IOException | InterruptedException e) {
            throw new RuntimeException(e);
        }
        return response.body();
    }

Espero que isso resolva o seu problema!

Armando bom dia tudo bem?

fiz algumas alterações no código só que agora ele não acessa a Api ou tem algum outro problema que não consigo identificar,... (tem poucos commits porque até iniciei outro projeto com outros nomes aff. só no github tem três aiai. ) poderia me ajudar por favor? no meu banco de dados aparecem os campos certinho. Mas na hora de clicar no primeiro item e procurar o livro fica horas o programa rodando e nada :(

git@github.com:ViviAkhemi/challengeLiterAlura.git

solução!

Bom dia, Viviane!

Analisando e testando o seu projeto consegui identificar alguns problemas e também a causa de porque a sua busca ficar horas rodando e não retornar nada. Falarei de cada problema a seguir.

  1. Sobre ficar rondando e não retornar nada: no seu primeiro método getLivraria quando você faz a coleta do nome do livro você chama o método nextLine duas vezes, sendo assim necessário passar a informação novamente. Logo, para ajustar isso, você deve chamar o método apenas uma vez. Segue um exemplo de como deve ficar o seu método:

    private DataLivraria getLivraria() {
        System.out.println("Digite o nome do livro que deseja buscar:");
        var bookName = scanner.nextLine();
    
        String json = consumoApi.obterJson(ENDERECO + bookName.replace(" ", "%20").toLowerCase().trim());
    
        var livraria = conversor.converterDados(json, DataLivraria.class);
        return livraria;
    
    }
    
  2. Propriedades não requisitadas: Após resolver a situação anterior, se você rodar o código e buscar um livro você receberá o erro "Unrecognized field "translators"", que ocorre porque você esqueceu de adicionar a Annotation para ignorar as propriedades que você não mapeou no Record DataLivro. Segue um exemplo como o Record DataLivro deve ficar:

    package com.br.alura.literalura.models;
    
    import com.fasterxml.jackson.annotation.JsonAlias;
    import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
    
    import java.util.List;
    
    @JsonIgnoreProperties(ignoreUnknown = true)
    public record DataLivro(Integer id,
                            @JsonAlias("title") String titulo,
                            @JsonAlias("authors") List<DataAutor> autores,
                            @JsonAlias("languages") String[] idiomas,
                            @JsonAlias("download_count") Integer downloads,
                            @JsonAlias("formats") DataFormatos formatos)
    
    {
    }
    
  3. Por fim, mas não menos importante, no arquivo principal da aplicação o LiteraluraApplication, você esqueceu de criar uma instância dos repositórios de Autor e livro, e passar elas no construtor da classe Principal. Esse arquivo corrigido ficará assim:

    package com.br.alura.literalura;
    
    import com.br.alura.literalura.models.Livro;
    import com.br.alura.literalura.principal.Principal;
    import com.br.alura.literalura.repositories.AutorRepository;
    import com.br.alura.literalura.repositories.LivroRepository;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class LiteraluraApplication implements CommandLineRunner {
        @Autowired
        private AutorRepository autorRepository;
        @Autowired
        private LivroRepository livroRepository;
    
        public static void main(String[] args) {
    
            SpringApplication.run(LiteraluraApplication.class, args);
        }
    
        @Override
        public void run(String... args) {
            Principal principal = new Principal(livroRepository, autorRepository);
            principal.exibeMenu();
        }
    }
    

Espero ter ajudado e caso tenha mais problemas estarei à disposição.

Bons estudos!

Armando muitissimo obrigada. Já estava ficando sem cabelos :)

bons estudos e trabalho pra você!