Как я могу использовать Spring RestTemplate для сопоставления вложенных данных с beans, где верхний уровень является переменной? - PullRequest
0 голосов
/ 18 июня 2020

У меня есть некоторые JSON данные вроде следующих. Я вижу другие решения, использующие bean-компонент в качестве оболочки для внутренних узлов, но в этих данных строка верхнего уровня не является именованным параметром («TSLA» и «LVS» ниже).

Я хотел бы использовать Spring RestTemplate и возвращать экземпляры Equity beans, которые содержат геттеры и сеттеры для каждого свойства, использующего 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
  }
}

Вот мой код. json.getBody() возвращает null, и я получаю 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();
}

Я пробовал использовать Jackson2 , но это не помогло. Я знаю, что отображение отключено в этом коде, но не вижу, как исправить это с помощью Spring.

1 Ответ

0 голосов
/ 18 июня 2020

После некоторого исследования я нашел решение, которое не использует RestTemplate, но использует API Джексона. Он читает дерево и создает объекты, используя значения из каждого узла.

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();
}
...