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

[Dúvida] Não estou conseguindo transformar o JSON do GoogleBooks no objeto Livro

Estou fazendo os exercícios de aula do curso, e decidi transformar a api do googlebooks no objeto livro, entretanto, minha saída está sendo null em todos os atributos.... Código principal:

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 PesquisaLivros {
    public static void main(String[] args) throws IOException, InterruptedException {
        Scanner scanner = new Scanner(System.in);
        System.out.println("Insira o nome do resposta que você deseja buscar:");
        var resposta = scanner.nextLine();

        String API_KEY = "***************************************"; //sem API key pra vocês haha
        String adress = "https://www.googleapis.com/books/v1/volumes?q=" + resposta + "&fields=items&key=" + API_KEY;
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(adress))
                .build();
        HttpResponse<String> response = client
                .send(request, HttpResponse.BodyHandlers.ofString());

        String json = response.body();
        Gson gson = new GsonBuilder()
                .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
                .create();

        Livro livro = gson.fromJson(json, Livro.class);
        System.out.println(livro);
    }
}

Record Livro:

public record Livro(String title, String[] authors, String publisher, String publishedDate) {
}

Saída:

Livro[title=null, authors=null, publisher=null, publishedDate=null]
2 respostas
solução!

Seu código parece estar correto em termos de estrutura para realizar a requisição HTTP e iniciar o processo de deserialização do JSON recebido. No entanto, o problema que você está enfrentando com os valores null na saída provavelmente está relacionado à estrutura do JSON retornado pela API do Google Books e como você está mapeando esses dados no seu objeto Livro.

A resposta JSON da API do Google Books é bastante aninhada e os dados que você está tentando extrair (title, authors, publisher, publishedDate) estão dentro de objetos aninhados, especificamente dentro de items[i].volumeInfo. Isso significa que você não pode mapeá-los diretamente para um Livro sem definir a estrutura completa ou sem processamento adicional.

Solução

Para resolver esse problema, você precisa adaptar seu código para lidar com a estrutura aninhada do JSON. Uma maneira de fazer isso é criar classes adicionais que representem a resposta completa, incluindo os objetos aninhados. Aqui está um exemplo de como você pode fazer isso:

Definição das Classes para a Estrutura do JSON

public class PesquisaLivrosResposta {
    private Item[] items;

    public Item[] getItems() {
        return items;
    }

    public void setItems(Item[] items) {
        this.items = items;
    }

    public static class Item {
        private VolumeInfo volumeInfo;

        public VolumeInfo getVolumeInfo() {
            return volumeInfo;
        }

        public void setVolumeInfo(VolumeInfo volumeInfo) {
            this.volumeInfo = volumeInfo;
        }
    }

    public static class VolumeInfo {
        private String title;
        private String[] authors;
        private String publisher;
        private String publishedDate;

        // Getters e Setters
    }
}

Modificação na Classe Principal

Agora, você precisa modificar a deserialização do JSON para usar a nova estrutura e depois extrair os dados desejados:

// Resto do código...

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

String json = response.body();

Gson gson = new GsonBuilder().create();

PesquisaLivrosResposta respostaLivros = gson.fromJson(json, PesquisaLivrosResposta.class);

if (respostaLivros.getItems().length > 0) {
    PesquisaLivrosResposta.VolumeInfo volumeInfo = respostaLivros.getItems()[0].getVolumeInfo();
    Livro livro = new Livro(volumeInfo.getTitle(), volumeInfo.getAuthors(), volumeInfo.getPublisher(), volumeInfo.getPublishedDate());
    System.out.println(livro);
} else {
    System.out.println("Nenhum livro encontrado.");
}

Observações

  • Este código assume que você está interessado apenas no primeiro livro retornado pela pesquisa. Você pode iterar sobre o array items se quiser processar múltiplos resultados.
  • Certifique-se de adicionar getters e setters na classe VolumeInfo para permitir que o Gson acesse os campos corretamente, ou você pode simplesmente tornar os campos públicos se preferir.
  • Adapte o record Livro e/ou a forma como você cria e exibe objetos Livro com base em quais dados você deseja apresentar.

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

Cara, muito obrigado. Resposta super rápida e precisa!