Spring Integration http: исходящий-шлюз с использованием json-частей - PullRequest
0 голосов
/ 02 мая 2018

Надеюсь, название понятно. Я использую Spring Integration, и я хотел бы сделать следующее. Я хотел бы использовать следующие API для обогащения полезной нагрузки: https://min -api.cryptocompare.com / data / pricemultifull? Fsyms = BTC & tsyms = USD

Как вы видите, у него есть структура типа RAW / BTC / USD /, а затем атрибуты. Меня интересуют только несколько значений атрибутов.

Мой исходящий-шлюз работает следующим образом:

<int:chain input-channel="internal.cryptocompare.coin.market.enrich.channel">
    <int-http:outbound-gateway id="cryptocompareHttpGateway.marketData" 
        url="https://min-api.cryptocompare.com/data/pricemultifull?fsyms={fsym}&amp;tsyms={tsyms}"
        http-method="GET" 
        reply-timeout="10000" 
        charset="UTF-8"
    >
        <int-http:uri-variable name="fsym" expression="payload.symbol" />
        <int-http:uri-variable name="tsyms" expression="'USD'" />
    </int-http:outbound-gateway>
</int:chain>

Затем я получу ResponseEntity, который я хотел бы получить, например, атрибуты. ЦЕНА.

Вместо того, чтобы иметь ResponseEntity, у меня также был бы объект значения, который я тоже мог бы использовать, но поля не были обогащены:

<int:enricher id="coinMarketEnricher"
    input-channel="internal.cryptocompare.coin.price.enriched.income.channel"
    request-channel="internal.cryptocompare.coin.market.enrich.channel"
    output-channel="cryptocompare.income.channel"
    error-channel="cryptocompare.error.channel"
>
    <int:property name="volume24hUSD" expression="payload.volume24hUSD"/>
    <int:property name="marketCapUSD" expression="payload.marketCapUSD"/>
    <int:property name="availableSupply" expression="payload.availableSupply"/>
    <int:property name="changePercent24h" expression="payload.changePercent24h"/>
    <int:property name="lastUpdateEpoch" expression="payload.lastUpdateEpoch"/>
    <int:property name="marketName" expression="payload.marketName"/>
</int:enricher>

<int:channel id="internal.cryptocompare.coin.market.enrich.channel" />

<int:chain input-channel="internal.cryptocompare.coin.market.enrich.channel">
    <int-http:outbound-gateway id="cryptocompareHttpGateway.marketData" 
        url="https://min-api.cryptocompare.com/data/pricemultifull?fsyms={fsym}&amp;tsyms={tsyms}"
        http-method="GET" 
        reply-timeout="10000" 
        charset="UTF-8"
        expected-response-type="net.hemisoft.ccm.porter.cryptocompare.Coin"
    >
        <int-http:uri-variable name="fsym" expression="payload.symbol" />
        <int-http:uri-variable name="tsyms" expression="'USD'" />
    </int-http:outbound-gateway>
</int:chain>

@ToString
class Coin {
    @JsonProperty("Id")                 String  coinId
    @JsonProperty("CoinName")           String  name
    @JsonProperty("Name")               String  symbol
    @JsonProperty("SortOrder")          Integer rank
    @JsonProperty("USD")                Double  priceUSD
    @JsonProperty("BTC")                Double  priceBTC
    @JsonProperty("VOLUME24HOUR")       Double  volume24hUSD
    @JsonProperty("MKTCAP")             Double  marketCapUSD
    @JsonProperty("SUPPLY")             Double  availableSupply
    @JsonProperty("CHANGEPCT24HOUR")    Double  changePercent24h
    @JsonProperty("LASTUPDATE")         Long    lastUpdateEpoch
    @JsonProperty("LASTMARKET")         String  marketName
}

Я бы предпочел использовать Coin_Class, а не Response-Entity. Большое спасибо за ваш вклад.

1 Ответ

0 голосов
/ 02 мая 2018

Для этого вам нужно добавить это:

expected-response-type="Coin"

в <int-http:outbound-gateway> определении: https://docs.spring.io/spring-integration/docs/5.0.4.RELEASE/reference/html/http.html#_httprequestexecutingmessagehandler

В дополнение к приведенному выше замечанию относительно пустых тел ответов, если ответ содержит тело, вы должны предоставить соответствующий атрибут expected-response-type или, опять же, вы просто получите ResponseEntity без тела.

UPDATE

Поскольку JSON, который вы получаете, не соответствует вашей модели Coin, вы можете сделать это следующим образом:

  • Отправка new Coin на internal.cryptocompare.coin.price.enriched.income.channel
  • request-channel="internal.cryptocompare.coin.market.enrich.channel" будет выполнять HTTP-запрос
  • Там вместо expected-response-type="net.hemisoft.ccm.porter.cryptocompare.Coin" вы должны использовать expected-response-type="java.lang.String"
  • Затем в этих <int:property> для сопоставления необходимо выполнить #jsonPath(), чтобы извлечь необходимые значения, например, <int:property name="volume24hUSD" expression="#jsonPath(payload, '$..VOLUME24HOUR[1]')"/>

Подробнее см. Здесь: https://docs.spring.io/spring-integration/docs/5.0.4.RELEASE/reference/html/spel.html и здесь: https://github.com/json-path/JsonPath

...