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

Leitura de Json com mais de um item

Prezados, bom dia!

Para fins de prática, criei uma aplicação que busca via API externa da ANBIMA a relação de fundos de investimentos em um ambiente de teste. A busca resulta em um JSON com aproximadamente 19 mil elementos, nesse formato:

{
    "total_elements": 19034,
    "size": 1000,
    "page": 0,
    "content": [{
        "codigo_fundo": "000191",
        "nome_fantasia": "BRADESCO H FC FIA ACUMULACAO",
        "cnpj_fundo": "77054658000100",
        "classe_anbima": "Ações",
        "situacao_atual": "A",
        "data_inicio_divulgacao_cota": "1967-07-03",
        "data_atualizacao": "2019-06-13T11:12:00"
    }, {
        "codigo_fundo": "000231",
        "nome_fantasia": "BRADESCO PRIME FIC DE FIA ACTIVE",
        "cnpj_fundo": "54069422000142",
        "classe_anbima": "Ações",
        "situacao_atual": "A",
        "data_inicio_divulgacao_cota": "1980-01-01",
        "data_atualizacao": "2019-06-13T11:12:00"
    }, {
        "codigo_fundo": "000612",
        "nome_fantasia": "BB ACOES IBRX INDEXADO FC FI",
        "cnpj_fundo": "30847180000102",
        "classe_anbima": "Ações",
        "situacao_atual": "A",
        "data_inicio_divulgacao_cota": "1980-01-01",
        "data_atualizacao": "2019-06-17T17:55:00"
    }, {
        "codigo_fundo": "000779",
        "nome_fantasia": "ITAU PERSONNALITE ACOES IBRX ATIVO FICFI",
        "cnpj_fundo": "56573470000107",
        "classe_anbima": "Ações",
        "situacao_atual": "A",
        "data_inicio_divulgacao_cota": "1980-01-01",
        "data_atualizacao": "2019-06-13T12:25:00"
    }, {
        "codigo_fundo": "000981",
        "nome_fantasia": "BRADESCO PRIME FIC DE FIA INDEX",
        "cnpj_fundo": "27865070000169",
        "classe_anbima": "Ações",
        "situacao_atual": "A",
        "data_inicio_divulgacao_cota": "1980-01-01",
        "data_atualizacao": "2019-06-13T11:12:00"
    }, {
        "codigo_fundo": "001082",
        "nome_fantasia": "FIC FIA BRB ACOES 500",
        "cnpj_fundo": "31937303000169",
        "classe_anbima": "Ações",
        "situacao_atual": "A",
        "data_inicio_divulgacao_cota": "1980-01-01",
        "data_atualizacao": "2019-07-17T16:53:00"
    }, {
        "codigo_fundo": "001643",
        "nome_fantasia": "ELITE FUNDO DE INVESTIMENTO EM ACOES",
        "cnpj_fundo": "28709046000101",
        "classe_anbima": "Ações",
        "situacao_atual": "A",
        "data_inicio_divulgacao_cota": "1980-01-01",
        "data_atualizacao": "2020-02-07T18:00:00"
    }]

}

O código de teste da API é o seguinte:

public class TestaApi {
    public static void main(String[] args) throws IOException, InterruptedException {

        Gson gson = new Gson();
        String jSonRespApi;
        HeaderFactory header = new HeaderFactory();
        header.criaToken(header); /* método para criar token de acesso a API */
        System.out.println("montado: " + header.getAcessToken() + " " + header.getTokenType() + " " + header.getExpiracao());

                String jsonFundo = """
                {"codigo_fundo":"000191","nome_fantasia":"BRADESCO H FC FIA ACUMULACAO","cnpj_fundo":"77054658000100","classe_anbima":"Ações","situacao_atual":"A","data_inicio_divulgacao_cota":"1967-07-03","data_atualizacao":"2019-06-13T11:12:00"}
                """;

            HttpClient client = HttpClient.newHttpClient();
            String[] headerAPI = {"Content-Type", "application/json", "client_id", "0O04L6t6nlhq", "access_token", header.getAcessToken()};
            HttpRequest request = HttpRequest.newBuilder().headers(headerAPI).uri(URI.create("https://api-sandbox.anbima.com.br/feed/fundos/v1/fundos"))
                    .build();
            HttpResponse<String> response = client.send(request,HttpResponse.BodyHandlers.ofString());
            jSonRespApi = response.body();

            FileWriter writer = new FileWriter("fundos.json");
            writer.write(jSonRespApi);
            writer.close();  /* gerou o JSON com sucesso */

           FundoRendaFixa rendaFixaarquivo =  gson.fromJson("fundos.json",FundoRendaFixa.class); /* apresenta erro: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $ */

           FundoRendaFixa rendaFixaresponse =  gson.fromJson(jSonRespApi,FundoRendaFixa.class);
           FundoRendaFixa rendaFixaString =  gson.fromJson(jsonFundo,FundoRendaFixa.class);

       //   System.out.println("Lido do Arquivo: " + rendaFixaarquivo);
            System.out.println("Lido do Response.body: " +rendaFixaresponse);  /* Lido do Response.body: null, null, Fundo Renda Fixa: null, null */
            System.out.println("Lido da String com linha única: " +rendaFixaString);  /* Lido da String com linha única: 000191, 77054658000100, Fundo Renda Fixa: BRADESCO H FC FIA ACUMULACAO, 1967-07-03 */
        }
    }

Como devo proceder para que o "rendaFixaResponse", que lê o JSON com mais de um registro passe as informações para o objeto da mesma maneira que o "rendaFixaString", que lê o Json com uma linha?

2 respostas
solução!

Olá Flávio, tudo bem?

Para ler o JSON com mais de um registro, você precisa fazer algumas alterações em seu código. No trecho em que você está usando o método fromJson para converter o JSON em um objeto da classe FundoRendaFixa, você precisa passar o tipo correto de objeto que está sendo retornado pelo JSON. No caso, o JSON que você está lendo contém um objeto com quatro campos: total_elements, size, page e content. O campo content é um array de objetos contendo as informações dos fundos de investimento.

Para ler corretamente esse JSON, você precisa criar uma classe que represente a estrutura do objeto retornado pelo JSON. Essa classe deve ter os mesmos campos do objeto retornado pelo JSON, com os tipos de dados correspondentes. Além disso, você precisa criar uma classe para representar cada objeto contido no array content.

Por exemplo, você pode criar uma classe FundoResponse para representar cada objeto contido no array content. Essa classe deve ter os mesmos campos que aparecem em cada objeto do array, com os tipos de dados correspondentes. Em seguida, você pode criar uma classe ApiResponse para representar o objeto retornado pelo JSON. Essa classe deve ter os campos total_elements, size, page e content, sendo que o campo content deve ser um array de objetos da classe FundoResponse.

Com essas classes criadas, você pode usar o método fromJson para converter o JSON em um objeto da classe ApiResponse. Em seguida, você pode percorrer o array content do objeto retornado e criar um objeto da classe FundoRendaFixa para cada elemento do array. Por fim, você pode adicionar esses objetos em uma lista ou em outro tipo de coleção, dependendo do que você precisa fazer com eles.

Espero ter ajudado e bons estudos!

Obrigado Matheus, rodou de primeira. Abraços