0

I'm currently calling this API https://cdn.jsdelivr.net/gh/fawazahmed0/currency-api@1/latest/currencies/gbp.json

This has the path param of gbp which then is included in the response

{
    "date": "2021-09-14",
    "gbp": {
        // omitted for brevity
    }
}

Im using the RestTemplate.getForObject method to make the GET HTTP request which is successful however i am not sure how i would go about typing the response.

I will be calling this url with multiple different path parameters. So for example https://cdn.jsdelivr.net/gh/fawazahmed0/currency-api@1/latest/currencies/eur.json is valid which will result in a response of

{
    "date": "2021-09-14",
    "eur": {
        // omitted for brevity
    }
}

So its not as easy as typing a gbp property on the response as Map<String, Double> etc. And i dont want to create a different class for each possible response.

So my question basically is. How can i type this? I've tried to use a custom @JsonDeserialzer annotation on a class which represents the data however since it does not know the key that was a bit of a dead end.

Is the only way to achieve this by using a custom ObjectMapper where i can pass the key to a customer deserializer rather than using the annotation?

Jack Wilkinson
  • 477
  • 3
  • 14

1 Answers1

0

First, consider using WebClient instead of RestTemplate, if you're on spring framework 5 (or switch to the webflux stack).

You don't need a custom ObjectMapper, but can just loop the properties by using restTemplate.getForEntity, like:

ResponseEntity<String> response = restTemplate.getForEntity
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(response.getBody());
Iterator<Map.Entry<String, JsonNode>> it = root.fields();
while (it.hasNext()) {
  Map.Entry<String, JsonNode> field = it.next();
  System.out.println("key: " + field.getKey());
   
  //Add some logic here ;)
  //Probably you want the second property, if it exists ...
  if (it.hasNext) {
    field = it.next();
    JsonNode currencyNode = field.getValue();
  }
}

If you need or want an object, try the @JsonAnySetter - see fe. here Unstable behavior with Jackson Json and @JsonAnySetter

rémy
  • 1,026
  • 13
  • 18