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

如何使用Jackson映射未知可变字段?汇率JSON反序列化报错处理

解决JSON汇率数据反序列化问题

报错的核心原因是JSON中的rates是一个键值对对象(键为货币代码,值为汇率),但你定义的Java实体类CurrencyExchangeRateResponse中,rates字段被声明为List<Rate>类型。Jackson无法自动将JSON对象转换为List集合,因此抛出类型不匹配的异常。

以下是两种可行的解决方案:

方案一:直接使用Map映射(最简单)

修改CurrencyExchangeRateResponse中的rates字段类型为Map<Currency, Double>,直接匹配JSON的键值对结构:

import lombok.Getter;
import lombok.Setter;
import java.util.Map;

@Getter
@Setter
public class CurrencyExchangeRateResponse {
    private Boolean success;
    private Boolean historical;
    private String date;
    private long timestamp;
    private String base;
    // 替换List<Rate>为Map,键是Currency枚举,值为汇率
    private Map<Currency, Double> rates;
}
  • 注意:Currency枚举的枚举值必须和JSON中的货币代码完全一致(包括大小写)。如果存在大小写不匹配的情况,可在枚举值上添加@JsonProperty注解指定映射关系,例如:
public enum Currency {
    AUD,
    @JsonProperty("GBP") // 若JSON中是小写"gbp",则改为@JsonProperty("gbp")
    GBP,
    HKD,
    // 其他货币代码
}

方案二:自定义反序列化器(保留List结构)

如果业务逻辑必须使用List<Rate>,可以编写自定义Jackson反序列化器,将JSON对象转换为List集合:

步骤1:编写自定义反序列化器

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class RatesListDeserializer extends JsonDeserializer<List<Rate>> {
    @Override
    public List<Rate> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        JsonNode ratesNode = p.getCodec().readTree(p);
        List<Rate> rateList = new ArrayList<>();
        
        // 遍历JSON对象的所有键值对
        Iterator<Map.Entry<String, JsonNode>> fieldIterator = ratesNode.fields();
        while (fieldIterator.hasNext()) {
            Map.Entry<String, JsonNode> entry = fieldIterator.next();
            Rate rate = new Rate();
            // 将货币代码字符串转换为Currency枚举
            rate.setCurrency(Currency.valueOf(entry.getKey()));
            // 将JSON值转换为Double类型
            rate.setValue(entry.getValue().asDouble());
            rateList.add(rate);
        }
        return rateList;
    }
}

步骤2:在实体类字段上指定反序列化器

修改CurrencyExchangeRateResponse的rates字段,添加@JsonDeserialize注解指定自定义反序列化器:

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import lombok.Getter;
import lombok.Setter;
import java.util.List;

@Getter
@Setter
public class CurrencyExchangeRateResponse {
    private Boolean success;
    private Boolean historical;
    private String date;
    private long timestamp;
    private String base;
    // 指定使用自定义反序列化器
    @JsonDeserialize(using = RatesListDeserializer.class)
    private List<Rate> rates;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 01:52:47