Home > Blockchain >  Parsing a nested json using gson
Parsing a nested json using gson

Time:03-07

What I am trying to do is to parse nested json data into a Java object using Gson and print it out with customized toString().

The Json Content

{"data": [
    {
        "symbol": "BTC",
        "circulating_supply": 18975050,
        "last_updated": "2022-03-05T13:54:00.000Z",
        "total_supply": 18975050,
        "cmc_rank": 1,
        "self_reported_circulating_supply": null,
        "platform": null,
        "tags": [
            "mineable",
            "pow",
            "sha-256",
            "store-of-value",
            "state-channel",
            "coinbase-ventures-portfolio",
            "three-arrows-capital-portfolio",
            "polychain-capital-portfolio",
            "binance-labs-portfolio",
            "blockchain-capital-portfolio",
            "boostvc-portfolio",
            "cms-holdings-portfolio",
            "dcg-portfolio",
            "dragonfly-capital-portfolio",
            "electric-capital-portfolio",
            "fabric-ventures-portfolio",
            "framework-ventures-portfolio",
            "galaxy-digital-portfolio",
            "huobi-capital-portfolio",
            "alameda-research-portfolio",
            "a16z-portfolio",
            "1confirmation-portfolio",
            "winklevoss-capital-portfolio",
            "usv-portfolio",
            "placeholder-ventures-portfolio",
            "pantera-capital-portfolio",
            "multicoin-capital-portfolio",
            "paradigm-portfolio"
        ],
        "date_added": "2013-04-28T00:00:00.000Z",
        "quote": {"USD": {
            "fully_diluted_market_cap": 820131199762.62,
            "last_updated": "2022-03-05T13:54:00.000Z",
            "market_cap_dominance": 42.252,
            "percent_change_30d": 6.81621153,
            "percent_change_1h": -0.42008562,
            "percent_change_24h": -5.71623656,
            "market_cap": 741049072478.8419,
            "volume_change_24h": -11.0241,
            "price": 39053.8666553628,
            "percent_change_60d": -16.6843952,
            "volume_24h": 26123993408.855915,
            "percent_change_90d": -21.03603335,
            "percent_change_7d": -0.10097865
        }},
        "num_market_pairs": 9214,
        "name": "Bitcoin",
        "max_supply": 21000000,
        "id": 1,
        "self_reported_market_cap": null,
        "slug": "bitcoin"
    },
    {
        "symbol": "ETH",
        "circulating_supply": 119834013.5615,
        "last_updated": "2022-03-05T13:54:00.000Z",
        "total_supply": 119834013.5615,
        "cmc_rank": 2,
        "self_reported_circulating_supply": null,
        "platform": null,
        "tags": [
            "mineable",
            "pow",
            "smart-contracts",
            "ethereum-ecosystem",
            "coinbase-ventures-portfolio",
            "three-arrows-capital-portfolio",
            "polychain-capital-portfolio",
            "binance-labs-portfolio",
            "blockchain-capital-portfolio",
            "boostvc-portfolio",
            "cms-holdings-portfolio",
            "dcg-portfolio",
            "dragonfly-capital-portfolio",
            "electric-capital-portfolio",
            "fabric-ventures-portfolio",
            "framework-ventures-portfolio",
            "hashkey-capital-portfolio",
            "kenetic-capital-portfolio",
            "huobi-capital-portfolio",
            "alameda-research-portfolio",
            "a16z-portfolio",
            "1confirmation-portfolio",
            "winklevoss-capital-portfolio",
            "usv-portfolio",
            "placeholder-ventures-portfolio",
            "pantera-capital-portfolio",
            "multicoin-capital-portfolio",
            "paradigm-portfolio",
            "injective-ecosystem",
            "bnb-chain"
        ],
        "date_added": "2015-08-07T00:00:00.000Z",
        "quote": {"USD": {
            "fully_diluted_market_cap": 316405371023.81,
            "last_updated": "2022-03-05T13:54:00.000Z",
            "market_cap_dominance": 18.0363,
            "percent_change_30d": 1.39750424,
            "percent_change_1h": -0.82066438,
            "percent_change_24h": -3.20839994,
            "market_cap": 316405371023.81366,
            "volume_change_24h": -14.3764,
            "price": 2640.363629825611,
            "percent_change_60d": -31.31982292,
            "volume_24h": 12406258074.91051,
            "percent_change_90d": -37.45316954,
            "percent_change_7d": -4.71064229
        }},
        "num_market_pairs": 5543,
        "name": "Ethereum",
        "max_supply": null,
        "id": 1027,
        "self_reported_market_cap": null,
        "slug": "ethereum"
    },
 and so on...
]}

POJO Classes : Example

package controller;

import java.util.List;
import javax.annotation.processing.Generated;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

@Generated("jsonschema2pojo")
public class Example {

    @SerializedName("data")
    @Expose
    private List<JsonFormatter> data = null;

    public List<JsonFormatter> getData() {
        return data;
    }

    public void setData(List<JsonFormatter> data) {
        this.data = data;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(Example.class.getName()).append('@').append(Integer.toHexString(System.identityHashCode(this))).append('[');
        sb.append("data");
        sb.append('=');
        sb.append(((this.data == null)?"<null>":this.data));
        sb.append(',');
        if (sb.charAt((sb.length()- 1)) == ',') {
            sb.setCharAt((sb.length()- 1), ']');
        } else {
            sb.append(']');
        }
        return sb.toString();
    }

}

POJO Classes : JsonFormatter

package controller;


import java.util.List;
import javax.annotation.processing.Generated;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

@Generated("jsonschema2pojo")
public class JsonFormatter {

    @SerializedName("symbol")
    @Expose
    private String symbol;
    @SerializedName("circulating_supply")
    @Expose
    private Float circulatingSupply;
    @SerializedName("last_updated")
    @Expose
    private String lastUpdated;
    @SerializedName("total_supply")
    @Expose
    private Float totalSupply;
    @SerializedName("cmc_rank")
    @Expose
    private Float cmcRank;
    @SerializedName("self_reported_circulating_supply")
    @Expose
    private Object selfReportedCirculatingSupply;
    @SerializedName("platform")
    @Expose
    private Platform platform;
    @SerializedName("tags")
    @Expose
    private List<String> tags = null;
    @SerializedName("date_added")
    @Expose
    private String dateAdded;
    @SerializedName("quote")
    @Expose
    private Quote quote;
    @SerializedName("num_market_pairs")
    @Expose
    private Float numMarketPairs;
    @SerializedName("name")
    @Expose
    private String name;
    @SerializedName("max_supply")
    @Expose
    private Float maxSupply;
    @SerializedName("id")
    @Expose
    private Integer id;
    @SerializedName("self_reported_market_cap")
    @Expose
    private Object selfReportedMarketCap;
    @SerializedName("slug")
    @Expose
    private String slug;

    public String getSymbol() {
        return symbol;
    }

    public void setSymbol(String symbol) {
        this.symbol = symbol;
    }

    public Float getCirculatingSupply() {
        return circulatingSupply;
    }

    public void setCirculatingSupply(Float circulatingSupply) {
        this.circulatingSupply = circulatingSupply;
    }

    public String getLastUpdated() {
        return lastUpdated;
    }

    public void setLastUpdated(String lastUpdated) {
        this.lastUpdated = lastUpdated;
    }

    public Float getTotalSupply() {
        return totalSupply;
    }

    public void setTotalSupply(Float totalSupply) {
        this.totalSupply = totalSupply;
    }

    public Float getCmcRank() {
        return cmcRank;
    }

    public void setCmcRank(Float cmcRank) {
        this.cmcRank = cmcRank;
    }

    public Object getSelfReportedCirculatingSupply() {
        return selfReportedCirculatingSupply;
    }

    public void setSelfReportedCirculatingSupply(Object selfReportedCirculatingSupply) {
        this.selfReportedCirculatingSupply = selfReportedCirculatingSupply;
    }

    public Platform getPlatform() {
        return platform;
    }

    public void setPlatform(Platform platform) {
        this.platform = platform;
    }

    public List<String> getTags() {
        return tags;
    }

    public void setTags(List<String> tags) {
        this.tags = tags;
    }

    public String getDateAdded() {
        return dateAdded;
    }

    public void setDateAdded(String dateAdded) {
        this.dateAdded = dateAdded;
    }

    public Quote getQuote() {
        return quote;
    }

    public void setQuote(Quote quote) {
        this.quote = quote;
    }

    public Float getNumMarketPairs() {
        return numMarketPairs;
    }

    public void setNumMarketPairs(Float numMarketPairs) {
        this.numMarketPairs = numMarketPairs;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Float getMaxSupply() {
        return maxSupply;
    }

    public void setMaxSupply(Float maxSupply) {
        this.maxSupply = maxSupply;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Object getSelfReportedMarketCap() {
        return selfReportedMarketCap;
    }

    public void setSelfReportedMarketCap(Object selfReportedMarketCap) {
        this.selfReportedMarketCap = selfReportedMarketCap;
    }

    public String getSlug() {
        return slug;
    }

    public void setSlug(String slug) {
        this.slug = slug;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(JsonFormatter.class.getName()).append('@').append(Integer.toHexString(System.identityHashCode(this))).append('[');
        sb.append("symbol");
        sb.append('=');
        sb.append(((this.symbol == null)?"<null>":this.symbol));
        sb.append(',');
        sb.append("circulatingSupply");
        sb.append('=');
        sb.append(((this.circulatingSupply == null)?"<null>":this.circulatingSupply));
        sb.append(',');
        sb.append("lastUpdated");
        sb.append('=');
        sb.append(((this.lastUpdated == null)?"<null>":this.lastUpdated));
        sb.append(',');
        sb.append("totalSupply");
        sb.append('=');
        sb.append(((this.totalSupply == null)?"<null>":this.totalSupply));
        sb.append(',');
        sb.append("cmcRank");
        sb.append('=');
        sb.append(((this.cmcRank == null)?"<null>":this.cmcRank));
        sb.append(',');
        sb.append("selfReportedCirculatingSupply");
        sb.append('=');
        sb.append(((this.selfReportedCirculatingSupply == null)?"<null>":this.selfReportedCirculatingSupply));
        sb.append(',');
        sb.append("platform");
        sb.append('=');
        sb.append(((this.platform == null)?"<null>":this.platform));
        sb.append(',');
        sb.append("tags");
        sb.append('=');
        sb.append(((this.tags == null)?"<null>":this.tags));
        sb.append(',');
        sb.append("dateAdded");
        sb.append('=');
        sb.append(((this.dateAdded == null)?"<null>":this.dateAdded));
        sb.append(',');
        sb.append("quote");
        sb.append('=');
        sb.append(((this.quote == null)?"<null>":this.quote));
        sb.append(',');
        sb.append("numMarketPairs");
        sb.append('=');
        sb.append(((this.numMarketPairs == null)?"<null>":this.numMarketPairs));
        sb.append(',');
        sb.append("name");
        sb.append('=');
        sb.append(((this.name == null)?"<null>":this.name));
        sb.append(',');
        sb.append("maxSupply");
        sb.append('=');
        sb.append(((this.maxSupply == null)?"<null>":this.maxSupply));
        sb.append(',');
        sb.append("id");
        sb.append('=');
        sb.append(((this.id == null)?"<null>":this.id));
        sb.append(',');
        sb.append("selfReportedMarketCap");
        sb.append('=');
        sb.append(((this.selfReportedMarketCap == null)?"<null>":this.selfReportedMarketCap));
        sb.append(',');
        sb.append("slug");
        sb.append('=');
        sb.append(((this.slug == null)?"<null>":this.slug));
        sb.append(',');
        if (sb.charAt((sb.length()- 1)) == ',') {
            sb.setCharAt((sb.length()- 1), ']');
        } else {
            sb.append(']');
        }
        return sb.toString();
    }

}

There are also other classes for my POJO, and the way I tried to parse it into Gson is :

Gson gson = new Gson();
Type type = new TypeToken<Map<String, ArrayList<JsonFormatter>>>() {}.getType();
Map<String, ArrayList<Example>> nodeProperties = gson.fromJson(json.toString(), type);

but when I try to print out its sub values like

for (Map.Entry<String, ArrayList<Example>> set : nodeProperties.entrySet()) {
            System.out.println(set.getValue().get(0).getData().get(0).toString());
        }

I get the error :

class controller.JsonFormatter cannot be cast to class controller.Example (controller.JsonFormatter and controller.Example are in unnamed module of loader 'app')

What I want to achieve is to print the above json content as like this:

Symbol: BTC
Circulating_supply: 18975050
...
Tags:
    mineable

Can anyone please help me out to solve this problem? Thanks in advance!

CodePudding user response:

The issue is in these lines:

Type type = new TypeToken<Map<String, ArrayList<JsonFormatter>>>() {}.getType();
Map<String, ArrayList<Example>> nodeProperties = gson.fromJson(json.toString(), type);

The TypeToken is for Map<String, ArrayList<JsonFormatter>>, but you store the parsed JSON in a variable of type Map<String, ArrayList<Example>>. Unfortunately Gson.fromJson(..., Type) does not provide any type safety guarantees, therefore you must make sure that the provided Type matches the type of the variable you store the result in. Additionally due to Java's type erasure at runtime, you do not notice this JsonFormatter vs. Example mismatch until you iterate over the elements, causing the ClassCastException.

Based on the JSON data you provided, it looks to me like you could just use gson.fromJson(json.toString(), Example.class), but please verify whether that is actually correct for your use case.

  • Related