How can I manipulate this JSON response obtained by RestTemplate to set a DTO object?

1.3k views Asked by At

I am working on a Spring Boot application and I have the following problem. I have to set values of a simple DTO object from the JSON output retrieved from a REST call.

Basically I am calling this GET API: https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=eur

As you can see it return a JSON response like this:

{
    "ethereum": {
        "eur": 2509.13
    }
}

So I have this CoingeckoPriceDTO class:

@Getter

@Setter
@NoArgsConstructor
@AllArgsConstructor
public class CoingeckoPriceDTO {
    
    String coin;
    BigDecimal price;
    
}

And then I have this service method:

@Service
@Log
public class CoingeckoInfoServiceImpl implements CoingeckoInfoService {
    
    @Autowired
    private RestTemplate restTemplate;
    
    String coinPriceApiUrl = "https://api.coingecko.com/api/v3/simple/price?ids={coinName}&vs_currencies={targetCurrency}";
    
    
    @Override
    public CoingeckoPriceDTO getCoinPrice(String coinName, String targetCurrency) {
        
        CoingeckoPriceDTO result = new CoingeckoPriceDTO();
        
        String completeUrl = this.coinPriceApiUrl.replace("{coinName}", coinName).replace("{targetCurrency}", targetCurrency);
        
        log.info("completeUrl: " + completeUrl);
        
        String responseStr = this.restTemplate.getForObject(completeUrl, String.class);
        
        log.info("responseStr: " + responseStr);
        
        
        return result;
    }
    
}

It simply perform the call via REST template then it print it as a string, and infact it print this string containing the expected JSON response as string:

responseStr: {"ethereum":{"eur":2499.04}}

Now my problem is to put these values into the previous CoingeckoPriceDTO fields. I think that I need to do some JSON manipulation to do it:

In particular I have to set my DTO String coin field with the ethereum string retrieved by the returned JSON (note that this is not the field value but it is the field name. I have no idea how to keep it and put it into my DTO object field). Then I have to set my DTO BigDecimal price field with the eur value in the JSON.

How can I implement a behavior like this?

1

There are 1 answers

1
GeoMldr On

Give it a try to change your class to something like this:

   public class CoingeckoPriceDTO {

        private String coin;

        @JsonAlias({"eur", "dol", "sek", "etc"})
        private BigDecimal price;

        public String getCoin() {
            return coin;
        }

        public void setCoin(String coin) {
            this.coin = coin;
        }

        public BigDecimal getPrice() {
            return price;
        }

        public void setPrice(BigDecimal price) {
            this.price = price;
        }
    }

Add to the @JsonAlias any currencies you intend to include.

And proceed to doing something like this:

public CoingeckoPriceDTO getCoinPrice(String coinName, String targetCurrency) throws JsonProcessingException {
    String completeUrl = coinPriceApiUrl.replace("{coinName}", coinName).replace("{targetCurrency}", targetCurrency);
    String responseStr = this.restTemplate.getForObject(completeUrl, String.class);
    JSONObject jsonObject = new JSONObject(responseStr);
    responseStr = jsonObject.getString("ethereum");

    ObjectMapper mapper = new ObjectMapper();
    CoingeckoPriceDTO result = mapper.readValue(responseStr, CoingeckoPriceDTO.class);

    result.setCoint(targetCurrency);

    return result;
}

I haven't run the code to see if it actually works, but you may make your adjustments if needed.