Home > Net >  Consuming JSON that may return a different data
Consuming JSON that may return a different data

Time:02-23

I'd like to write some java code using spring boot to consume JSON data from a specific endpoint. However with each request the response may return different data fields as such.

{"success":true,"terms":"https:\/\/coinlayer.com\/terms","privacy":"https:\/\/coinlayer.com\/privacy","timestamp":1645616586,"target":"USD","rates":{"BTC":39049.424242}}
{"success":true,"terms":"https:\/\/coinlayer.com\/terms","privacy":"https:\/\/coinlayer.com\/privacy","timestamp":1645626666,"target":"USD","rates":{"BTC":39061.184046,"ETH":2726.545731}}
{"success":true,"terms":"https:\/\/coinlayer.com\/terms","privacy":"https:\/\/coinlayer.com\/privacy","timestamp":1645626966,"target":"USD","rates":{"ADA":0.939301,"BTC":39006.990707,"ETH":2720.502765}}

and so on.

Below is my current code which deals with the first case presented. I could write another Rates.java to cater for the second case and so on but I'm looking to have one Rates.java file which deals with all possible cases.

LiveData.java

package com.example.consumingrest;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class LiveData {

    private Boolean success;
    private String terms;
    private String privacy;
    private Long timestamp;
    private String target;
    private Rates rates;

    public LiveData() {
    }

    public Boolean getSuccess() {
        return success;
    }

    public void setSuccess(Boolean success) {
        this.success = success;
    }

    public String getTerms() {
        return terms;
    }

    public void setTerms(String terms) {
        this.terms = terms;
    }

    public String getPrivacy() {
        return privacy;
    }

    public void setPrivacy(String privacy) {
        this.privacy = privacy;
    }

    public Long getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(Long timestamp) {
        this.timestamp = timestamp;
    }

    public String getTarget() {
        return target;
    }

    public void setTarget(String target) {
        this.target = target;
    }

    public Rates getRates() {
        return rates;
    }

    public void setValue(Rates rates) {
        this.rates = rates;
    }

    @Override
    public String toString() {
        return "LiveData{"  
                "success='"   success   '\''  
                "terms='"   terms   '\''  
                "privacy='"   privacy   '\''  
                "timestamp='"   timestamp   '\''  
                "target='"   target   '\''  
                "rates="   rates  
                '}';
    }
}

Rates.java

package com.example.consumingrest;
import java.math.BigDecimal;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Rates {
    @JsonProperty(value = "BTC")
    private BigDecimal btc;

    public Rates() {
    }

    public BigDecimal getBTC() {
        return this.btc;
    }

    public void setId(BigDecimal btc) {
        this.btc = btc;
    }


    @Override
    public String toString() {
        return "{"  
                "BTC='"   btc   '\'' 
                '}';
    }
}

ConsumingRest.java (main)

package com.example.consumingrest;

import java.time.LocalDate;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
public class ConsumingRestApplication {

    private static final Logger log = LoggerFactory.getLogger(ConsumingRestApplication.class);

    public static void main(String[] args) {
        SpringApplication.run(ConsumingRestApplication.class, args);
    }

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        return builder.build();
    }

    @Bean
    public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
        return args -> {
            LiveData liveData = restTemplate.getForObject(
                    "http://api.coinlayer.com/api/live?access_key=121a4df8b95fd5be872da3bad101cd73&target=EUR&symbols=BTC", LiveData.class);
            log.info(liveData.toString());
        };
    }
}

CodePudding user response:

As mentioned in the comments, seems you want a map containing the rates:

@JsonIgnoreProperties(ignoreUnknown = true)
public class LiveData {
    ...
    private Map<String, BigDecimal> rates;

See Mapping a Dynamic JSON Object

CodePudding user response:

Any Json Object can be parsed to Map<String, Object> where Object may be anything including Map or List. So, your map may be nested with any depth and it can contain Lists with any objects including maps. Any of your responses can be always parsed to that structure. So, return that structure and you won't have to worry about different formats - This is one size fits all.

  • Related