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

[Dúvida] Consulta à API do GitHub

Quando o programa encontra um usuário do GitHub, ele devolve os valores "nome" e "id" como "null"

Saída:

Digite o usuário do GitHub para consulta: f3l1pe-augusto

JSON: {"login":"f3l1pe-augusto","id":137817308,"node_id":"U_kgDOCDbs3A","avatar_url":"https://avatars.githubusercontent.com/u/137817308?v=4","gravatar_id":"","url":"https://api.github.com/users/f3l1pe-augusto","html_url":"https://github.com/f3l1pe-augusto","followers_url":"https://api.github.com/users/f3l1pe-augusto/followers","following_url":"https://api.github.com/users/f3l1pe-augusto/following{/other_user}","gists_url":"https://api.github.com/users/f3l1pe-augusto/gists{/gist_id}","starred_url":"https://api.github.com/users/f3l1pe-augusto/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/f3l1pe-augusto/subscriptions","organizations_url":"https://api.github.com/users/f3l1pe-augusto/orgs","repos_url":"https://api.github.com/users/f3l1pe-augusto/repos","events_url":"https://api.github.com/users/f3l1pe-augusto/events{/privacy}","received_events_url":"https://api.github.com/users/f3l1pe-augusto/received_events","type":"User","site_admin":false,"name":"Felipe","company":null,"blog":"","location":null,"email":null,"hireable":null,"bio":"Estudante de Sistemas de Informação","twitter_username":null,"public_repos":7,"public_gists":0,"followers":1,"following":2,"created_at":"2023-06-26T16:56:12Z","updated_at":"2023-10-12T18:21:02Z"}

USUÁRIO: Nome: null ID: null

Programa finalizado!

Main:

package br.com.fakecompany.main;

import br.com.fakecompany.exception.UserGitHubNotFoundException;
import br.com.fakecompany.models.Usuario;
import br.com.fakecompany.models.UsuarioGitHub;
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 Main {
    public static void main(String[] args) throws IOException, InterruptedException {
        Scanner scanner = new Scanner(System.in);

        System.out.println("Digite o usuário do GitHub para consulta: ");
        String username = scanner.nextLine();

        String address = "https://api.github.com/users/" + username;

        try {
            HttpClient client = HttpClient.newHttpClient();
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(address))
                    .header("Accept", "application/vnd.github+json")
                    .build();
            HttpResponse<String> response = client
                    .send(request, HttpResponse.BodyHandlers.ofString());

            if (response.statusCode() == 404) {
                throw new UserGitHubNotFoundException("Usuário do GitHub não encontrado!");
            }

            String json = response.body();

            System.out.println("JSON: " + json);

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

            UsuarioGitHub usuarioGitHub = gson.fromJson(json, UsuarioGitHub.class);
            System.out.println("\nUSUÁRIO GITHUB: " + usuarioGitHub);

            Usuario usuario = new Usuario(usuarioGitHub);
            System.out.println("\nUSUÁRIO: " + usuario);

        } catch (IOException | InterruptedException e) {
            System.out.println("\nOps... Houve um erro durante a consulta à API do GitHub.");
            e.printStackTrace();
        } catch (UserGitHubNotFoundException e) {
            System.out.println(e.getMessage());
        } finally {
            System.out.println("\nPrograma finalizado!");
        }
    }
}

Usuário:

package br.com.fakecompany.models;

public class Usuario {
    private String name;
    private String id;

    public Usuario (UsuarioGitHub usuarioGitHub) {
        this.name = usuarioGitHub.login();
        this.id = usuarioGitHub.id();
    }

    @Override
    public String toString() {
        return "Nome: " + name + "\nID: " + id;
    }
}

UsuárioGithub:

package br.com.fakecompany.models;

public class Usuario {
    private String name;
    private String id;

    public Usuario (UsuarioGitHub usuarioGitHub) {
        this.name = usuarioGitHub.login();
        this.id = usuarioGitHub.id();
    }

    @Override
    public String toString() {
        return "Nome: " + name + "\nID: " + id;
    }
}

UserGitHubNotFoundException:

package br.com.fakecompany.exception;

public class UserGitHubNotFoundException extends RuntimeException {
    private String message;

    public UserGitHubNotFoundException(String message) {
        this.message = message;
    }

    @Override
    public String getMessage() {
        return this.message;
    }
}
3 respostas

E aí, Felipe beleza?

Valeu por mandar teu código e explicar o rolo que tá rolando. Dei uma olhada e acho que tenho uma ideia do que tá acontecendo com esses valores "nome" e "id" ficando como "null" na hora de bater na API do GitHub.

1. Vamo entender essa atribuição:

Tá ligado na classe Usuario? Ela que deveria tá pegando os valores do nome e do ID do GitHub. Só que parece que tá pegando meio errado da classe UsuarioGitHub. Então, saca só isso.

2. Olha o JSON:

Quando você tá transformando o JSON da API do GitHub no objeto UsuarioGitHub, é chave ter certeza que os nomes das coisas batem certinho com os nomes na classe UsuarioGitHub.

Como dar um jeito nisso:

Bora conferir se os nomes dos campos no JSON da API do GitHub batem com os nomes na classe UsuarioGitHub.

public class UsuarioGitHub {
    private String login; // Olha se bate com o "name" do JSON
    private int id;
    // Outras paradas...

    // Getters e setters
}

Na classe Usuario, vê se tá usando os getters da classe UsuarioGitHub certinho:

public class Usuario {
    private String name;
    private String id;

    public Usuario(UsuarioGitHub usuarioGitHub) {
        this.name = usuarioGitHub.getLogin(); // Usa os getters certos
        this.id = String.valueOf(usuarioGitHub.getId()); // Se precisar, converte pra String
    }

    @Override
    public String toString() {
        return "Nome: " + name + "\nID: " + id;
    }
}

Tá ligado no tratamento de exceções quando o usuário não é encontrado? Só dá uma conferida pra ter certeza que tá tudo certo.

} catch (IOException | InterruptedException e) {
    System.out.println("\nOps... Deu ruim na hora de pegar os dados do GitHub.");
    e.printStackTrace();
} catch (UserGitHubNotFoundException e) {
    System.out.println(e.getMessage());
}

Se liga, dá uma printada nos valores depois de transformar o objeto UsuarioGitHub pra ver se tá tudo certo:

UsuarioGitHub usuarioGitHub = gson.fromJson(json, UsuarioGitHub.class);
System.out.println("Nome do GitHub: " + usuarioGitHub.getLogin()); // Vê se tá pegando certo
System.out.println("ID do GitHub: " + usuarioGitHub.getId()); // Dá um check aqui

Usuario usuario = new Usuario(usuarioGitHub);
System.out.println("\nUSUÁRIO: " + usuario);

Então, dá uma olhada pra ver se tá tudo batendo entre os nomes no JSON e os nomes na classe UsuarioGitHub. E não esquece de usar os getters certinhos na classe Usuario.

Espero que isso te ajude! Tamo junto!

Olá!

No UsuarioGitHub uso uma Record, como ensinado em aula, então não consigo fazer os métodos getters e setters, e na verdade o JSON retorna, por exemplo, {"login":"f3l1pe-augusto","id":137817308}, o que coincide com os parâmetros criados, o tratamento de exceções funciona como esperado, o problema está realmente no fato do login e o id chegarem nulos na record. Percebi que tinha mandado duas vezes a mesma classe na pergunta anterior, desculpe.

Essa é a Record UsuarioGitHub, apenas troquei o nome:

package br.com.fakecompany.models;

public record GitHubUser(String login, int id) {
}
solução!

Olá!

Descobri que meu erro estava no seguinte trecho de código:

                    .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)

Na verdade, não era preciso usar nenhum caso especial de FieldNamingPolicy, então para o programar rodar como esperado é só excluir essa parte.