使用RestTemplate反序列化键动态变化的货币API返回JSON的方法咨询
方案1:使用@JsonAnySetter注解(最简便,推荐)
这是Jackson自带的原生注解,专门处理JSON中存在未知动态key的场景,不需要自定义反序列化器,也不需要提前预知币种代码。
首先定义通用响应类:
import com.fasterxml.jackson.annotation.JsonAnySetter; import java.util.Collections; import java.util.HashMap; import java.util.Map; public class CurrencyApiResponse { private String date; private final Map<String, Map<String, Double>> currencyRateMap = new HashMap<>(); public String getDate() { return date; } public void setDate(String date) { this.date = date; } // 所有未匹配到类属性的JSON键值对都会自动进入该方法 @JsonAnySetter public void addCurrencyRate(String currencyCode, Map<String, Double> rateMap) { currencyRateMap.put(currencyCode, rateMap); } // 便捷方法:直接获取当前接口返回的汇率数据(单次请求只会存在一个币种key) public Map<String, Double> getCurrentRate() { return currencyRateMap.values().stream().findFirst().orElse(Collections.emptyMap()); } // 也支持根据传入的币种代码定向获取汇率 public Map<String, Double> getRateByCode(String currencyCode) { return currencyRateMap.get(currencyCode.toLowerCase()); } }
使用时直接调用RestTemplate即可:
CurrencyApiResponse response = restTemplate.getForObject(requestUrl, CurrencyApiResponse.class); // 直接获取解析完成的汇率数据 Map<String, Double> rates = response.getCurrentRate();
该方案零额外配置,代码量最少,完全满足你的需求。
方案2:使用JsonNode手动解析
如果不想在实体类上加注解,也可以先接收为原始JSON节点,再手动提取数据:
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.core.type.TypeReference; import java.util.Map; import java.util.Iterator; // 调用接口获取原始JSON节点 JsonNode responseNode = restTemplate.getForObject(requestUrl, JsonNode.class); // 提取日期字段 String date = responseNode.get("date").asText(); // 遍历找到动态币种key String currencyKey = null; for (Iterator<String> it = responseNode.fieldNames(); it.hasNext(); ) { String field = it.next(); if (!"date".equals(field)) { currencyKey = field; break; } } // 将币种对应的节点转换为汇率Map ObjectMapper objectMapper = new ObjectMapper(); Map<String, Double> rates = objectMapper.convertValue(responseNode.get(currencyKey), new TypeReference<Map<String, Double>>() {});
方案3:自定义反序列化器(不推荐)
完全不需要用到这个方案,前两种实现成本更低、维护更简单。你之前尝试的自定义注解方案走不通的原因就是反序列化器无法在运行时拿到你传入的路径参数,确实需要额外构造带参数的反序列化器,实现成本高,没有必要。
内容的提问来源于stack exchange,提问作者Jack Wilkinson
相关产品推荐
相关产品推荐

