4
respostas

[Projeto] Projeto Consumindo API

package br.com.alura.screenmatch.principal;
import br.com.alura.screenmatch.modelos.Books;
import br.com.alura.screenmatch.modelos.Livro;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Scanner;

public class SeachBook {
    public static void main(String[] args) throws IOException, InterruptedException {
        Scanner scanner = new Scanner(System.in);
        System.out.println("Digite o Livro que estar Procurando: ");
        var buscar = scanner.nextLine().trim();
        System.out.println("Adicione a chave de validação");
        var chave = scanner.nextLine().trim();

        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://www.googleapis.com/books/v1/volumes?q=" + buscar +
                        "&key=" + chave))
                .build();
        HttpResponse<String> response = client
                .send(request, HttpResponse.BodyHandlers.ofString());
        //System.out.println(response.body());
        String json = response.body();
        Gson gson = new GsonBuilder()
                .setFieldNamingPolicy(FieldNamingPolicy
                        .UPPER_CAMEL_CASE).create();
        Livro livro = gson.fromJson(json, Livro.class);
        System.out.println("Convertido");
        Books meulivro = new Books(livro);
        System.out.println(meulivro);
    }
}
package br.com.alura.screenmatch.modelos;

import com.google.gson.annotations.SerializedName;

public class Books {
    @SerializedName("title")
    String titulo;
    @SerializedName("authors")
    String autor;
    @SerializedName("publisher")
    String editora;
    @SerializedName("description")
    String descricao;

    public Books(String title, String authors, String publisher, String description) {
        this.titulo = title;
        this.autor = authors;
        this.editora = publisher;
        this.descricao = description;
    }

    public Books(Livro book) {
        this.titulo = book.title();
        this.autor = book.authors();
        this.editora = book.publisher();
        this.descricao = book.description();
    }

    public String getTitulo() {
        return titulo;
    }

    public String getAutor() {
        return autor;
    }

    public String getEditora() {
        return editora;
    }

    public String getDescricao() {
        return descricao;
    }

    @Override
    public String toString() {
        return "Books{" +
                "titulo='" + titulo + '\'' +
                ", autor='" + autor + '\'' +
                ", editora='" + editora + '\'' +
                ", descricao='" + descricao + '\'' +
                '}';
    }
}
package br.com.alura.screenmatch.modelos;

public record Livro(String title, String authors, String publisher, String description) {

}
4 respostas

Mesmo não dando erro na hora de mostra o resultado aparece como Null, não conseguir identifica ainda o erro

Oi, Reinaldo! Tudo bem?

O problema aqui é que a estrutura JSON retornada pela API do Google Books não está no formato esperado pela sua classe Livro. O JSON possui uma hierarquia onde os dados dos livros estão dentro de um array chamado items, e cada item tem uma chave volumeInfo, que é onde estão title, authors, publisher e description.

Sua classe Livro precisa representar essa estrutura corretamente. Resolva fazendo o seguinte:

  1. Crie uma nova classe para representar volumeInfo:

    
     package br.com.alura.screenmatch.modelos;
    
     public record VolumeInfo(String title, String[] authors, String publisher, String description) {
     }
     
  2. Crie uma classe para representar os items do JSON:

    
     package br.com.alura.screenmatch.modelos;
    
     public record Item(VolumeInfo volumeInfo) {
     }
     
  3. Agora, crie uma classe que representa a resposta da API:

    
     package br.com.alura.screenmatch.modelos;
    
     import java.util.List;
    
     public record Resultado(List items) {
     }
     
  4. No seu código principal, ajuste a deserialização:

    
     Gson gson = new GsonBuilder()
         .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
         .create();
    
     Resultado resultado = gson.fromJson(json, Resultado.class);
    
     if (resultado.items().isEmpty()) {
         System.out.println("Nenhum livro encontrado.");
         return;
     }
    
     VolumeInfo info = resultado.items().get(0).volumeInfo();
     Books meulivro = new Books(
         info.title(),
         String.join(", ", info.authors()),
         info.publisher(),
         info.description()
     );
     System.out.println(meulivro);
     
  5. Por fim, ajuste o construtor da sua classe Books para aceitar os parâmetros corretamente, como String para autores (usamos String.join para juntar o array).

Com isso, os dados não vão mais aparecer como null.

Espero ter ajudado e bons estudos!

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

Eu fiz as implementações porem a ultima parte ficou assim, também não entendi o que o senhor quis dizer com a classe Books
Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Oi, Reinaldo! Peço desculpas pela demora em responder!

Vendo o erro da imagem “Cannot resolve method 'volumeInfo' in 'Object’”, o problema está na deserialização da resposta JSON: o Gson está convertendo os itens da lista como objetos genéricos (Object), e não como instâncias da classe Item, que você deveria ter definido como:


package br.com.alura.screenmatch.modelos;

public record Item(VolumeInfo volumeInfo) {
}

O que precisa ser corrigido agora é o tipo genérico da List dentro da classe Resultado. Ela deve especificar que é uma lista de Item, assim:


package br.com.alura.screenmatch.modelos;

import java.util.List;

public record Resultado(List<Item> items) {
}

Sem esse tipo definido, o Gson entende que é uma List&lt;Object&gt;, e por isso você não consegue chamar volumeInfo().

Além disso, ajuste a deserialização no seu main para refletir isso:


Gson gson = new GsonBuilder()
    .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
    .create();

Resultado resultado = gson.fromJson(json, Resultado.class);

if (resultado.items().isEmpty()) {
    System.out.println("Nenhum livro encontrado.");
    return;
}

VolumeInfo info = resultado.items().get(0).volumeInfo();
Books meulivro = new Books(
    info.title(),
    String.join(", ", info.authors()),
    info.publisher(),
    info.description()
);
System.out.println(meulivro);

Assim você garante que o Gson sabe como mapear a estrutura da API e que o método volumeInfo() será reconhecido.

Fico à disposição.