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

Jackson反序列化CoinMarketCap API含伪对象数组的JSON字符串问题

嘿,我之前也踩过CoinMarketCap这个v2 API的坑!这个data字段确实有点反直觉——明明看起来是一组币种数据,却做成了以币种ID为键的命名键值对,而非标准数组,给POJO映射添了不少麻烦。下面给你几个实用的解决办法,不管你用Jackson还是Gson都能轻松搞定:

方法一:用Jackson的Map<Integer, YourCoinPOJO>直接接收

这是最直接的方案,因为API返回的data本质就是一个键为数字ID、值为币种对象的映射。

首先定义你的币种实体类,对应单个币种的字段:

public class Coin {
    private int id;
    private String name;
    private String symbol;
    private double price_usd;
    // 按需添加其他字段,记得加上getter和setter
}

然后定义外层的响应类,用Map来接收data字段:

public class CmcTickerResponse {
    private Map<Integer, Coin> data;
    private Status status; // 可选,如果你需要处理API返回的状态信息
    // getter和setter
}

// 可选的Status类,对应API返回的status字段
public class Status {
    private String timestamp;
    private int error_code;
    // 其他状态字段
}

解析的时候就用常规的Jackson ObjectMapper:

ObjectMapper mapper = new ObjectMapper();
CmcTickerResponse response = mapper.readValue(apiResponseString, CmcTickerResponse.class);
// 要是想转成List方便遍历,直接取Map的values就行
List<Coin> coinList = new ArrayList<>(response.getData().values());
方法二:用Gson处理同样的Map结构

如果你习惯用Gson,思路和上面一致,只是解析方式略有不同。

同样先定义好Coin和CmcTickerResponse类,然后解析时借助TypeToken:

Gson gson = new Gson();
Type responseType = new TypeToken<CmcTickerResponse>() {}.getType();
CmcTickerResponse response = gson.fromJson(apiResponseString, responseType);
List<Coin> coinList = new ArrayList<>(response.getData().values());
方法三:自定义反序列化器,直接转成List

如果不想用Map,希望data字段直接映射成List,可以自定义一个反序列化器来处理。

以Jackson为例,先写反序列化器:

public class CoinListDeserializer extends JsonDeserializer<List<Coin>> {
    @Override
    public List<Coin> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        JsonNode dataNode = p.getCodec().readTree(p);
        List<Coin> coinList = new ArrayList<>();
        // 遍历所有子节点,转成Coin对象
        for (JsonNode coinNode : dataNode) {
            Coin coin = p.getCodec().treeToValue(coinNode, Coin.class);
            coinList.add(coin);
        }
        return coinList;
    }
}

然后在响应类的data字段上加上注解指定使用这个反序列化器:

public class CmcTickerResponse {
    @JsonDeserialize(using = CoinListDeserializer.class)
    private List<Coin> data;
    private Status status;
    // getter和setter
}

这样解析后,response.getData()直接就是List<Coin>,不用再手动转换Map的值啦!

小提示

记得确保你的POJO字段名和API返回的JSON字段名一致,如果字段名不一样(比如你把price_usd改成priceUsd),要加上@JsonProperty("price_usd")(Jackson)或者@SerializedName("price_usd")(Gson)来做字段映射哦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:56:27