Spring Boot中Jackson如何映射无键第三方API JSON数组为自定义对象
解决无键名JSON数组映射到Java对象的问题
你遇到的是数组型JSON结构(无键名,纯按顺序排列元素),这种场景下@JsonProperty不能直接用来指定键名(因为根本没有键),但可以利用它的index属性配合构造方法,或者用@JsonFormat指定数组映射规则,以下是两种可行方案:
方案一:用@JsonFormat指定数组形状(依赖字段顺序)
通过@JsonFormat(shape = JsonFormat.Shape.ARRAY)告诉Jackson,这个类要按数组格式映射,字段顺序必须和JSON数组的元素顺序严格对应:
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @JsonFormat(shape = JsonFormat.Shape.ARRAY) @JsonIgnoreProperties(ignoreUnknown = true) // 忽略最后一个无用字段 public class Kline { // 字段顺序必须和JSON数组元素顺序完全一致 private long openTime; private String openPrice; private String highPrice; private String lowPrice; private String closePrice; private String volume; private long closeTime; private String quoteAssetVolume; private int numberOfTrades; private String takerBuyBaseVolume; private String takerBuyQuoteVolume; // 必须提供无参构造(Jackson默认需要) public Kline() {} // 生成getter和setter方法 public long getOpenTime() { return openTime; } public void setOpenTime(long openTime) { this.openTime = openTime; } public String getOpenPrice() { return openPrice; } public void setOpenPrice(String openPrice) { this.openPrice = openPrice; } // 其余getter/setter请自行补充 }
解析代码:
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.List; public class Main { public static void main(String[] args) throws Exception { String jsonString = "[[1499040000000,\"0.01634790\",\"0.80000000\",\"0.01575800\",\"0.01577100\",\"148976.11427815\",1499644799999,\"2434.19055334\",308,\"1756.87402397\",\"28.46694368\",\"0\"]]"; ObjectMapper mapper = new ObjectMapper(); // 外层是数组,所以映射为List<Kline> List<Kline> klines = mapper.readValue(jsonString, new TypeReference<List<Kline>>() {}); } }
方案二:用@JsonCreator构造方法+@JsonProperty(index)(更可靠)
通过构造方法接收参数,用@JsonProperty(index = N)指定每个参数对应JSON数组的索引位置,这种方式不依赖字段顺序,更清晰可控:
import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; public class Kline { private final long openTime; private final String openPrice; private final String highPrice; private final String lowPrice; private final String closePrice; private final String volume; private final long closeTime; private final String quoteAssetVolume; private final int numberOfTrades; private final String takerBuyBaseVolume; private final String takerBuyQuoteVolume; @JsonCreator public Kline( @JsonProperty(index = 0) long openTime, @JsonProperty(index = 1) String openPrice, @JsonProperty(index = 2) String highPrice, @JsonProperty(index = 3) String lowPrice, @JsonProperty(index = 4) String closePrice, @JsonProperty(index = 5) String volume, @JsonProperty(index = 6) long closeTime, @JsonProperty(index = 7) String quoteAssetVolume, @JsonProperty(index = 8) int numberOfTrades, @JsonProperty(index = 9) String takerBuyBaseVolume, @JsonProperty(index = 10) String takerBuyQuoteVolume // 索引11的无用字段直接忽略,不加入构造参数 ) { this.openTime = openTime; this.openPrice = openPrice; this.highPrice = highPrice; this.lowPrice = lowPrice; this.closePrice = closePrice; this.volume = volume; this.closeTime = closeTime; this.quoteAssetVolume = quoteAssetVolume; this.numberOfTrades = numberOfTrades; this.takerBuyBaseVolume = takerBuyBaseVolume; this.takerBuyQuoteVolume = takerBuyQuoteVolume; } // 生成getter方法 public long getOpenTime() { return openTime; } public String getOpenPrice() { return openPrice; } // 其余getter请自行补充 }
解析代码和方案一完全一致,因为外层都是数组结构。
注意事项
- JSON中价格类字段用字符串存储,Java类中建议用
String接收,避免浮点数精度丢失;时间戳、交易数这类整数可以直接用long/int接收。 - 如果JSON数组长度固定但有冗余字段,用
@JsonIgnoreProperties(ignoreUnknown = true)(方案一)或直接不接收对应参数(方案二)即可忽略。
内容的提问来源于stack exchange,提问作者BitQueen
相关产品推荐
相关产品推荐

