You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring中用RestTemplate解析Poloniex JSON数据遇空值问题

问题原因分析

我之前也碰到过类似的Poloniex API解析问题,你的情况大概率是JSON结构和实体类的映射没匹配上。Poloniex的returnTicker API返回的是以交易对名称为键的嵌套JSON对象,而不是直接包含BTC_ETH字段的平级结构。日志里的BTC_ETH{BTC_ETH=null}也能佐证这一点——你的实体类里可能错误定义了一个名为BTC_ETH的字段,但JSON顶层根本没有这个键,所以会被赋值为null。

解决方案步骤

1. 修正实体类结构

首先创建一个通用的交易对数据实体类(比如命名为TickerEntry),不要用交易对名称作为类名,用来映射单个交易对的详情:

import com.fasterxml.jackson.annotation.JsonProperty;

public class TickerEntry {
    private Integer id;
    @JsonProperty("last")
    private String lastPrice;

    // 必须添加无参构造函数(Jackson序列化/反序列化要求)
    public TickerEntry() {}

    // Getters & Setters
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getLastPrice() {
        return lastPrice;
    }

    public void setLastPrice(String lastPrice) {
        this.lastPrice = lastPrice;
    }

    // 可选:重写toString方便日志输出
    @Override
    public String toString() {
        return "TickerEntry{id=" + id + ", lastPrice='" + lastPrice + "'}";
    }
}

注:如果你的字段名和JSON键完全一致(比如用last代替lastPrice),可以省略@JsonProperty注解,Jackson会自动匹配。

2. 用RestTemplate接收为Map结构

因为API返回的是键值对集合,我们需要用ParameterizedTypeReference告诉RestTemplate把JSON解析成Map<String, TickerEntry>:

import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import org.springframework.core.ParameterizedTypeReference;

// 假设你已经通过Spring注入了RestTemplate实例
RestTemplate restTemplate = new RestTemplate();
String poloniexTickerUrl = "https://poloniex.com/public?command=returnTicker";

// 发送请求并解析响应
ResponseEntity<Map<String, TickerEntry>> response = restTemplate.exchange(
    poloniexTickerUrl,
    HttpMethod.GET,
    null,
    new ParameterizedTypeReference<Map<String, TickerEntry>>() {}
);

Map<String, TickerEntry> tickerMap = response.getBody();

3. 提取BTC_ETH的目标字段

现在直接从Map中取出BTC_ETH对应的实体即可:

if (tickerMap != null && tickerMap.containsKey("BTC_ETH")) {
    TickerEntry btcEthEntry = tickerMap.get("BTC_ETH");
    System.out.println("BTC_ETH id: " + btcEthEntry.getId());
    System.out.println("BTC_ETH last price: " + btcEthEntry.getLastPrice());
} else {
    System.err.println("未找到BTC_ETH的交易数据");
}

4. 检查RestTemplate的消息转换器

确保你的Spring配置中已经启用了Jackson的JSON转换器(默认会自动配置,也可以手动添加):

@Bean
public RestTemplate restTemplate() {
    RestTemplate restTemplate = new RestTemplate();
    restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
    return restTemplate;
}
为什么之前的写法会失败?

你之前创建BTC_ETH、BTC_BCN这类以交易对命名的实体类,然后直接用restTemplate.getForObject(url, BTC_ETH.class),相当于告诉Jackson“把整个JSON对象映射到BTC_ETH类的字段上”。但整个JSON的顶层是{"BTC_ETH": {...}, "BTC_BCN": {...}},你的BTC_ETH类里没有匹配的顶层字段,所以Jackson无法找到对应数据,最终返回的实例里所有字段都是null,就出现了你看到的日志输出。

内容的提问来源于stack exchange,提问作者Michu93

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:57:09