2
respostas

Desafio Api tabela FIPE

\Consumo API

package br.com.alura.TabelaFipe.Service;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class ConsumoApi {

public String obterDados(String endereco){

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

\Converte Dados

package br.com.alura.TabelaFipe.Service;	
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;

import java.util.Collection;
import java.util.List;

public class ConvertDados implements IConverteDados{
    private ObjectMapper mapper = new ObjectMapper();

@Override
public <T> T obterDados(String json, Class<T> classe) {
    try {
        return mapper.readValue(json,classe);
    } catch (JsonProcessingException e) {
        throw new RuntimeException(e);
    }
}

@Override
public <T> List<T> obeterLista(String json,Class<T> classe) {
    CollectionType lista = mapper.getTypeFactory()
            .constructCollectionType(List.class,classe);
    try {
        return mapper.readValue(json,lista);
    } catch (JsonProcessingException e) {
        throw new RuntimeException(e);
    }
}
}

\Dados Marca

package br.com.alura.TabelaFipe.model;

import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public record DadosMarcas(
        @JsonAlias("codigo") String codigo,
        @JsonAlias("nome")  String nome ) { }

\DadosModelo

package br.com.alura.TabelaFipe.model;
import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import java.util.List;
@JsonIgnoreProperties(ignoreUnknown = true)
public record DadosModelo(@JsonAlias("modelos") List<DadosMarcas> listModelos) {
}

\Dados Veiculo

package br.com.alura.TabelaFipe.model;

import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public record DadosVeiculo(
        @JsonAlias("TipoVeiculo") Integer tipoVeiculo,
        @JsonAlias("Valor") String valor,
        @JsonAlias("Marca") String marca,
        @JsonAlias("Modelo") String modelo,
        @JsonAlias("AnoModelo") Integer anoModelo,
        @JsonAlias("Combustivel") String combustivel,
        @JsonAlias("CodigoFipe") String codigoFipe,
        @JsonAlias("MesReferencia") String mesReferencia,
        @JsonAlias("SiglaCombustivel") String siglaCombustivel )
{
    @Override
    public String toString() {
        return "******************************************"+
                "\nTipo do Veiculo:" + this.tipoVeiculo +
                " Ano Modelo: " + this.anoModelo +
                " Modelo: " + this.modelo +
                "\n Marca: " + this.marca +
                "\n Combustivel: " + this.combustivel+ "-" + this.siglaCombustivel+
                "\n Valor Tabela Fipe: " + this.valor+
                "\n******************************************";



    }
}

\Tabela Fipe package br.com.alura.TabelaFipe;

import br.com.alura.TabelaFipe.principal.Principal;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class TabelaFipeApplication implements CommandLineRunner {

    public static void main(String[] args) {

        SpringApplication.run(TabelaFipeApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        Principal principal = new Principal();
        principal.exibeMenu();
    }
}
2 respostas

\Principal package br.com.alura.TabelaFipe.principal;

import br.com.alura.TabelaFipe.Service.ConsumoApi;
import br.com.alura.TabelaFipe.Service.ConvertDados;
import br.com.alura.TabelaFipe.model.DadosMarcas;
import br.com.alura.TabelaFipe.model.DadosModelo;
import br.com.alura.TabelaFipe.model.DadosVeiculo;
import com.fasterxml.jackson.databind.DeserializationContext;

import java.util.Comparator;
import java.util.List;
import java.util.Scanner;

public class Principal {

//Criação dos objetos de consumo de API e conversado dos dados
private ConsumoApi consumoApi= new ConsumoApi();
private ConvertDados conversor = new ConvertDados();
private Scanner leitura = new Scanner(System.in);
private final String ENDERECO = "https://parallelum.com.br/fipe/api/v1/" ;
        //"carros/marcas;
//private String jSon;



public void exibeMenu(){
    Integer opcao=0;
    String endereco=null;

    System.out.println("*************************");
    System.out.println("ESCOLHA O TIPO E VEÍCULO");
    System.out.println("*************************");
    System.out.println("1-CARROS");
    System.out.println("2-MOTOS");
    System.out.println("3-CAMINHÕES");
    System.out.println("4-SAIR");
    System.out.println("*************************");
    System.out.println("Digite uma opção válida: ");
    opcao = leitura.nextInt();
    if (opcao==1){ endereco = ENDERECO + "carros/marcas";}
    else if (opcao==2) {endereco = ENDERECO + "motos/marcas";}
    else if (opcao==3) {endereco = ENDERECO + "caminhoes/marcas";}
    //else if (opcao==4) {}
    var jSon = consumoApi.obterDados(ENDERECO+"carros/marcas");
    List<DadosMarcas> dadosMarca = conversor.obeterLista(jSon, DadosMarcas.class);

    //Listar os dados do veíuculo
    System.out.println("*******************");
    System.out.println("Lista das Marcas");
    System.out.println("*******************");
    dadosMarca.forEach(e-> {
        System.out.println("Codigo: " + e.codigo()+ " Nome: " + e.nome());
    });

    System.out.println("escolha um modelo :");
    var modelo = leitura.next();//
    jSon = consumoApi.obterDados(ENDERECO+"carros/marcas/"+modelo+"/modelos");
    DadosModelo dadosModelos = conversor.obterDados(jSon, DadosModelo.class);
    System.out.println(dadosModelos);

    System.out.println("*******************");
    System.out.println("Lista dos modelos");
    System.out.println("*******************");

    dadosModelos.listModelos().forEach(e->{
        System.out.println("Codigo: " + e.codigo()+ "Nome: " + e.nome());
    });

    System.out.println("****************************************");
    System.out.println("Lista dos modelos Ordenados por codigo");
    System.out.println("****************************************");
    dadosModelos.listModelos().stream().
            sorted(Comparator.comparing(DadosMarcas::codigo)).
            forEach(System.out::println);

    System.out.println("\nDigite um modelo :");
    var veiculo =  leitura.next();

    List<DadosMarcas> listVeiculosFilter = dadosModelos.listModelos().stream()
            .filter(e-> e.nome().toLowerCase().contains(veiculo.toLowerCase()))
            .sorted(Comparator.comparing(DadosMarcas::nome))
            .toList();

    //Lista dos Veículos Filtrados
    System.out.println("****************************");
    System.out.println("Lista de Veículos Filtrados");
    System.out.println("****************************");
    listVeiculosFilter.forEach(e-> {
        System.out.println("Codigo: "+e.codigo()+" Nome: "+e.nome());
    });

    System.out.println("Informo o veiculo desejado com base na listagem acima: ");
    var codigoVeiculo = leitura.next();

    jSon = consumoApi.obterDados(ENDERECO+"carros/marcas/"+modelo+"/modelos/"+codigoVeiculo+"/anos");
    List<DadosMarcas> listVeiculosAno = conversor.obeterLista(jSon, DadosMarcas.class);

    //List<DadosVeiculo> listVeiculosValores;
    listVeiculosAno.stream().sorted(Comparator.comparing(DadosMarcas::codigo)).toList()
            .forEach(e->{
              var jSonEnd = consumoApi.obterDados(ENDERECO+"carros/marcas/"+modelo+"/modelos/"+codigoVeiculo+"/anos/"+e.codigo());
              DadosVeiculo dadosVeiculo = conversor.obterDados(jSonEnd,DadosVeiculo.class) ;
              System.out.println(dadosVeiculo.toString());
            });

    }

    }

Obs.: Gostaria de um exemplo utilizando o jackson, onde pudéssemos converter os dados do json direto para uma lista e não um classe record.

Olá, Rogerio.

Tudo bem?

Parabéns pelo desafio! Isso mostra que está de fato praticando e evoluindo.

Gostaria de comentar sobre a organização do código e sugerir algumas melhorias. Primeiramente, é bom ver que você dividiu o código em diferentes classes, o que facilita a manutenção e compreensão. No entanto, você poderia considerar o uso de injeção de dependência para tornar o código mais flexível e testável.

Quanto ao exemplo de conversão de JSON para uma lista usando o Jackson, você pode modificar o método obeterLista na classe ConvertDados para aceitar uma classe Class<T> e retornar uma lista de objetos do tipo fornecido. Aqui está um exemplo:

// Modificação no método obeterLista em ConvertDados
public <T> List<T> obeterLista(String json, Class<T> classe) {
    CollectionType lista = mapper.getTypeFactory().constructCollectionType(List.class, classe);
    try {
        return mapper.readValue(json, lista);
    } catch (JsonProcessingException e) {
        throw new RuntimeException(e);
    }
}

// Exemplo de uso
String json = "your_json_string_here";
List<DadosMarcas> dadosMarcasList = conversor.obeterLista(json, DadosMarcas.class);

Dessa forma, você pode usar o mesmo método para converter JSON em listas de diferentes tipos, tornando o código mais genérico e reutilizável.

Além disso, seria interessante adicionar tratamento de exceções mais específico nos métodos da classe ConsumoApi para fornecer informações mais detalhadas sobre possíveis falhas na comunicação com a API.

Espero ter entendido e conseguido ajudar. Se precisar de ajuda, manda aqui. Bons estudos!