0

I have some JSON data like the following. I see other solutions using a bean as a wrapper to the inner nodes, but in this data, the top-level string is not a named parameter ("TSLA" and "LVS" below).

I'd like to use Spring RestTemplate and return instances of Equity beans that contain getters and setters for each property using Lombok.

{
  "TSLA": {
    "assetType": "EQUITY",
    "assetMainType": "EQUITY",
    "cusip": "88160R101",
    "symbol": "TSLA",
    "description": "Tesla, Inc.  - Common Stock",
    "bidPrice": 1001.88,
    "bidSize": 100,
    "bidId": "Q",
    "askPrice": 1002.17,
    "askSize": 100,
    "askId": "B",
    "lastPrice": 1001.88
  },
  "LVS": {
    "assetType": "EQUITY",
    "assetMainType": "EQUITY",
    "cusip": "517834107",
    "symbol": "LVS",
    "description": "Las Vegas Sands Corp. Common Stock",
    "bidPrice": 48.33,
    "bidSize": 200,
    "bidId": "P",
    "askPrice": 48.34,
    "askSize": 300,
    "askId": "P",
    "lastPrice": 48.33
  }
}

Here is my code. json.getBody() returns null and I get an NPE.

public Optional<List<Equity>> getQuotes(final String... tickers) {

//redacted the URL string creation.  I get the correct data with the URL.

    try {
        final ResponseEntity<JsonNode> json = restTemplate.getForEntity(url, JsonNode.class);
        List<Equity> equities = new ArrayList<>(tickers.length);

        for (String ticker : tickers) {
            Equity equity = mapper.readValue(Objects.requireNonNull(json.getBody()).get(ticker).toString(),
                    Equity.class);
            equities.add(equity);
        }
        return Optional.of(equities);

    } catch (Exception e) {
        log.error("Could not retrieve quote for " + Arrays.toString(tickers), e);
    }
    return Optional.empty();
}

I tried using Jackson2, but it had no effect. I know the mapping is off with this code, but I don't see how to correct it with Spring.

riddle_me_this
  • 8,575
  • 10
  • 55
  • 80

1 Answers1

0

After some exploration, I found a solution that doesn't use the RestTemplate, but uses the Jackson API. It reads the tree and creates the objects using the values from each node.

public Optional<List<Equity>> getQuotes(final String... tickers) {
    //URL creation redacted

    try {
        JsonNode node = mapper.readTree(new URL(url));
        List<Equity> equities = new ArrayList<>(tickers.length);

        for (String ticker : tickers) {
            JsonNode topLevel = node.path(ticker);
            Equity equity = mapper.treeToValue(topLevel, Equity.class);
            equities.add(equity);
        }
        return Optional.of(equities);

    } catch (Exception e) {
        log.error("Could not retrieve quote for " + Arrays.toString(tickers), e);
    }
    return Optional.empty();
}
riddle_me_this
  • 8,575
  • 10
  • 55
  • 80