DEV Community

Cover image for [JAVA - PT-BR] CONSUMINDO UMA API DE CEP
Eduardo Teixeira
Eduardo Teixeira

Posted on

[JAVA - PT-BR] CONSUMINDO UMA API DE CEP

Recentemente resolvi aprender um pouco mais sobre a programação em Java e desde então tenho consultado bastante conteúdo usar esta linguagem com foco no consumo e desenvolvimento de API's.

CONSUMINDO UME ENDPOINT
Um endpoint é o endereço utilizado para poder fazer requisições a um servidor, neste caso temos o exemplo abaixo para a nossa integração.
viacep.com.br/ws/01001000/json/

Vamos utilizar algumas ferramentas para poder realizar o teste das requisições, neste caso será utilizado o Postman, eu gosto de utilizar a plataforma pois dá um suporte a documentação entre outras ferramentas que podem ser utilizadas para fazer requisições.

Retorno obtido:

{
    "cep": "01001-000",
    "logradouro": "Praça da Sé",
    "complemento": "lado ímpar",
    "bairro": "Sé",
    "localidade": "São Paulo",
    "uf": "SP",
    "ibge": "3550308",
    "gia": "1004",
    "ddd": "11",
    "siafi": "7107"
}
Enter fullscreen mode Exit fullscreen mode

Com base no retorno que tivemos vamos acessar o site JsonSchema2 para criarmos o nosso projeto em Java, basicamente é uma ferramenta que faz o mapeamento do retorno JSON e com isto cria as variáveis, métodos de encapsulamento para que podemos utilizar após o retorno obtido da API.

Image description

Após isto, clique em preview e veja se obteve um resultado semelhante a este:

Image description

Clique na opção zip para baixar o projeto.

Após obter o código do projeto, vamos extrair e para manipular o arquivo estarei utilizando a ferramenta Eclipse.

| Como abrir um projeto no Eclipse

Com o projeto aberto, localize a classe gerada e remova essa anotação @Generated("jsonschema2pojo")
e o import import javax.annotation.Generated;
pois ela não será útil, perceba que a plataforma gerou os métodos getteers e setteers e já está pronto para uso.

Classe Endereco


package br.consultacep;

import java.util.HashMap;
import java.util.Map;

public class Endereco {

    private String cep;
    private String logradouro;
    private String complemento;
    private String bairro;
    private String localidade;
    private String uf;
    private String ibge;
    private String gia;
    private String ddd;
    private String siafi;
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    public String getCep() {
        return cep;
    }

    public void setCep(String cep) {
        this.cep = cep;
    }

    public String getLogradouro() {
        return logradouro;
    }

    public void setLogradouro(String logradouro) {
        this.logradouro = logradouro;
    }

    public String getComplemento() {
        return complemento;
    }

    public void setComplemento(String complemento) {
        this.complemento = complemento;
    }

    public String getBairro() {
        return bairro;
    }

    public void setBairro(String bairro) {
        this.bairro = bairro;
    }

    public String getLocalidade() {
        return localidade;
    }

    public void setLocalidade(String localidade) {
        this.localidade = localidade;
    }

    public String getUf() {
        return uf;
    }

    public void setUf(String uf) {
        this.uf = uf;
    }

    public String getIbge() {
        return ibge;
    }

    public void setIbge(String ibge) {
        this.ibge = ibge;
    }

    public String getGia() {
        return gia;
    }

    public void setGia(String gia) {
        this.gia = gia;
    }

    public String getDdd() {
        return ddd;
    }

    public void setDdd(String ddd) {
        this.ddd = ddd;
    }

    public String getSiafi() {
        return siafi;
    }

    public void setSiafi(String siafi) {
        this.siafi = siafi;
    }

    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }
}
Enter fullscreen mode Exit fullscreen mode

Crie uma outra classe para converter JSON em String, neste caso eu criei a Util, vamos precisar também de uma biblioteca gson pois nela terá uma classe e métodos que auxiliará na conversão.

package br.utilitarios;

import java.io.BufferedReader;
import java.io.IOException;

public class Util {
    public static String converteJsonEmString(BufferedReader buffereReader) throws IOException {
        String resposta, jsonString = "";
        while ((resposta = buffereReader.readLine()) != null) {
            jsonString += resposta;
        }
        return jsonString;
    }

}

Enter fullscreen mode Exit fullscreen mode

Crie uma nova classe para podermos fazer a requisição da API, neste exemplo eu criei a IntegracaoAPI:

package br.consultacep;

import br.utilitarios.Util;

import com.google.gson.Gson;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class IntegracaoAPI {    
    public static Endereco buscaCep (String cep) throws Exception {
        String enderecoURL = "https://viacep.com.br/ws/" + cep + "/json/";
        URL url = new URL(enderecoURL);
        HttpURLConnection conexao = (HttpURLConnection) url.openConnection();
        conexao.setRequestMethod("GET");
        conexao.setDoInput(true);
        try {
            BufferedReader buff = new BufferedReader(new InputStreamReader((conexao.getInputStream()), "utf-8"));

            String convertJsonString = Util.converteJsonEmString(buff);
            Gson gson = new Gson();
            Endereco endereco = gson.fromJson(convertJsonString, Endereco.class);
            return endereco;

        } catch (Exception msgErro) {
            throw  new Exception("Erro de conexão- status Code [" + conexao.getResponseCode() + "]. " + msgErro.toString()); 
        }

    }

}
Enter fullscreen mode Exit fullscreen mode

DEBUG CLASS INTEGRAÇÃO API

  • Foi criado uma método que recebe como parâmetro um cep e retorna uma classe do tipo Endereço.
  • Em seguida, foi aberto uma conexão e obtemos um retorno que é armazenado na variável buff, com isto é necessário que haja uma conversão do de JSON para String e com isto realizarmos a manipulação dos dados.
  • Quando retornado os dados o método fromJson faz um mapeamento do que foi retornado com a nossa classe Endereço, sendo assim os atributos e variáveis devem ter os mesmos nomes para que haja pontos em comuns e com isto manipular os dados corretamente.

Por último, crie uma classe para exibir os dados retornados da API:

package br.consultacep;


import java.util.Scanner;

public class Principal {

    public static void main(String[] args) throws Exception {
        System.out.print("Informe seu CEP: ");
        String cep = new Scanner(System.in).nextLine();
        Endereco endereco = IntegracaoAPI.buscaCep(cep);

        System.out.println("CEP Consultado: ");
        System.out.println("Complemento: ");
        System.out.println("Logradouro: " + endereco.getLogradouro());
        System.out.println("Bairro: " + endereco.getBairro());
        System.out.println("Localidade: " + endereco.getLocalidade());
        System.out.println("DDD: " + endereco.getDdd());

    }   
}

Enter fullscreen mode Exit fullscreen mode

Basta executar o projeto e informar um CEP, o resultado será este:

Image description

Clonagem de repositório:
https://github.com/EDUARDO-TEIXEIRA/ConsultaCEP-API.git

Referências

Top comments (5)

Collapse
 
wldomiciano profile image
Wellington Domiciano

Muito legal vc estar estudando Java também, Eduardo! Testei aqui sua solução e funcionou certinho.

Se vc estiver usando as versão mais recentes do Java, tipo a partir da versão 11, tem umas coisas que dá para melhorar.

Por exemplo a forma como vc faz a requisição. A partir do Java 11 tem um jeito bem interessante de fazer este tipo de coisa, veja só:

final HttpRequest request = HttpRequest
  .newBuilder(URI.create("https://viacep.com.br/ws/%s/json/".formatted(cep)))
  .build();

final HttpClient client = HttpClient.newHttpClient();

final HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
Enter fullscreen mode Exit fullscreen mode

Tem um canal que eu acompanho no YouTube, o RinaldoDev, que tem uns vídeos explicando melhor como funciona este novo recurso, vale a pena olhar, pois ele explica muito bem:

Outra coisa legal é que a classe Endereço poderia ser um record. Eu nunca tinha usado o Gson, mas pelo que pesquisei ele não funciona com records (ou eu que não consegui fazer funcionar ^^). De qualquer forma, se vc trocar ele pelo Jackson, fica uma maravilha, olha só:

private record Endereco(
  String cep,
  String logradouro,
  String complemento,
  String bairro,
  String localidade,
  String uf,
  String ibge,
  String gia,
  String ddd,
  String siafi
) {
}

final ObjectMapper objectMapper = new ObjectMapper();

final Endereco endereco = objectMapper.readValue(response.body(), Endereco.class);

System.out.println(endereco);
Enter fullscreen mode Exit fullscreen mode

Desde o Java 9 vc não precisa transformar o InputStream num BufferedReader para ter linha a linha. Vc pode ter todos os bytes de uma vez só e já passar para String, assim:

import java.nio.charset.StandardCharsets;
// ...
String convertJsonString = new String(conexao.getInputStream().readAllBytes(), StandardCharsets.UTF_8);
Enter fullscreen mode Exit fullscreen mode

Aqui um exemplo completo incluindo os imports:

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.net.http.HttpResponse.BodyHandlers;

import com.fasterxml.jackson.databind.ObjectMapper;

public class Main2 {
  private record Endereco(
    String cep,
    String logradouro,
    String complemento,
    String bairro,
    String localidade,
    String uf,
    String ibge,
    String gia,
    String ddd,
    String siafi
  ) {
  }

  public static void main(String... args) throws IOException, InterruptedException {
    final String cep = "29010004";

    final HttpRequest request = HttpRequest
      .newBuilder(URI.create("https://viacep.com.br/ws/%s/json/".formatted(cep)))
      .build();

    final HttpClient client = HttpClient.newHttpClient();

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

    final ObjectMapper objectMapper = new ObjectMapper();

    final Endereco endereco = objectMapper.readValue(response.body(), Endereco.class);

    System.out.println("CEP Consultado: " + cep);
    System.out.println("Complemento: " + endereco.complemento());
    System.out.println("Logradouro: " + endereco.logradouro());
    System.out.println("Bairro: " + endereco.bairro());
    System.out.println("Localidade: " + endereco.localidade());
    System.out.println("DDD: " + endereco.ddd());
  }
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
eduardo_teixeira profile image
Eduardo Teixeira

Muito bom Wellington! Obrigado por compartilhar seus conhecimentos.

O único problema que tenho hoje é que o ERP que eu trabalho atualmente está em uma versão Java 7 e com isto eu utilizo o consumo de métodos mais antigos para ter compatibilidade para fazer os métodos de requisição.

Gostei da simplicidade que está em novas versões, com bem menos linhas consegue fazer mais. De qualquer forma, estatei testando aqui na minha máquina.❤

Collapse
 
wldomiciano profile image
Wellington Domiciano

Ah, vc trabalha com a versão 7, entendi.

Sim, as novas versões trouxeram coisas muito legais.

Vale a pena testar mesmo, pelo menos para estar antenado. Vai que surge a oportunidade de atualizar o sistema, né?

Thread Thread
 
eduardo_teixeira profile image
Eduardo Teixeira

Sim, todo o framework é em uma versão mais antiga, mas com certeza é bom saber dessas novidades! Gostei da simplificidade no momento em que você mostrou para a chamada das requisições.

Collapse
 
fvalente profile image
Fábio Valente • Edited

Parabéns, muito bom o artigo.
Sou dev de outras áreas e tecnologias, mas consegui resolver com algumas buscas no google, rodar no VisualStudio Code, hoje.
Foram necessárias algumas adaptações, maioria dos códigos que precisei criar ou alterar utilizei editores online, mas começou a ficar chato e como tenho pouca experiência com o Java no VS Code (no Eclipse um pouco mais), apanhei um pouco.
Tive problemas de versão, depois de classe. mas consegui fazer funcionar.
Estou testando consumo de API em Java (para um novo serviço que vou desenvolver).

Próximo passo será simular um servidor externo (Totvs Datasul), você teria algum artigo que cria uma API, personalizável, para eu testar se meu envio (utilizando uma lib java dentro do PTC Windchill) vai funcionar?
Preciso validar se vou receber o JSON como esperado, e responder simulando o servidor real (que o ambiente QAS vai demorar um pouco para ficar pronto).

Sobre as diferenças do projeto atualmente que me lembrei:
Se for ajudar alguém, ocorreram algumas mudanças.
A variável Scanner está dando erro, resolvi assim:

Scanner cep = new Scanner(System.in);
Endereco endereco = IntegracaoAPI.buscaCep(cep.nextLine()); 
Enter fullscreen mode Exit fullscreen mode

E a função que usou da biblioteca java.net.URL está depreciada, e tive de usar a java.net.URI com o seguinte código para evitar os warnings do editor:

URI uri = new URI(enderecoURL);
URL url = uri.toURL();
Enter fullscreen mode Exit fullscreen mode

Mais uma vez, obrigado!