如何从大型 json 文件中获取特定集合
How to get a specific collection from a large json file
我正在尝试从大型 json 文件中获取特定集合,但我不想在 json 文件上创建所有对象结构,因为我只需要 "calls" 和 "puts" 字段...
这是我的 class 选项...不发布 getter 和 setter..
public class Option {
public enum Type { PUT, CALL }
@JsonIgnore
public Type type;
@JsonProperty("contractSymbol")
private String contractSymbol;
@JsonProperty("contractSize")
private String contractSize;
@JsonProperty("currency")
private String currency;
@JsonProperty("inTheMoney")
private boolean inTheMoney;
@JsonProperty("percentChange")
private Field percentChange;
@JsonProperty("strike")
private Field strike;
@JsonProperty("change")
private Field change;
@JsonProperty("impliedVolatility")
private Field impliedVolatility;
@JsonProperty("ask")
private Field ask;
@JsonProperty("bid")
private Field bid;
@JsonProperty("lastPrice")
private Field lastPrice;
@JsonProperty("volume")
private LongFormatField volume;
@JsonProperty("lastTradeDate")
private LongFormatField lastTradeDate;
@JsonProperty("expiration")
private LongFormatField expiration;
@JsonProperty("openInterest")
private LongFormatField openInterest;
}
我正在尝试获取这样的数据...
List<Option> res = JSON_MAPPER.readValue(new URL(link), new TypeReference<List<Option>>() {});
for(Option o: res){
o.type = Option.Type.CALL;
System.out.println(o.toString());
}
Aa,这是个例外...
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token
at [Source: https://query2.finance.yahoo.com/v7/finance/options/AEIS?formatted=true&lang=en-US®ion=US&corsDomain=finance.yahoo.com; line: 1, column: 16] (through reference chain: java.util.HashMap["optionChain"])
问题是源中的 json return 以对象 属性、"optionChain" 开头,杰克逊试图将其反序列化为 HashMap
,但你期望在反序列化后得到一个 List
。
正如你提到的,你只需要 json 中的 "calls" 和 "puts",你可以使用 ObjectMapper.readTree
先得到整个 JsonNode
,然后通过JsonNode.findValue
找到"calls"的节点,最后反序列化该节点。下面是一个例子:
String link = "https://query2.finance.yahoo" +
".com/v7/finance/options/AEIS?formatted=true&lang=en-US®ion=US&corsDomain=finance.yahoo.com";
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(new URL(link));
JsonNode calls = jsonNode.findValue("calls");
List<Option> callOptions = mapper.readValue(calls.traverse(), new TypeReference<List<Option>>() {});
我正在尝试从大型 json 文件中获取特定集合,但我不想在 json 文件上创建所有对象结构,因为我只需要 "calls" 和 "puts" 字段...
这是我的 class 选项...不发布 getter 和 setter..
public class Option {
public enum Type { PUT, CALL }
@JsonIgnore
public Type type;
@JsonProperty("contractSymbol")
private String contractSymbol;
@JsonProperty("contractSize")
private String contractSize;
@JsonProperty("currency")
private String currency;
@JsonProperty("inTheMoney")
private boolean inTheMoney;
@JsonProperty("percentChange")
private Field percentChange;
@JsonProperty("strike")
private Field strike;
@JsonProperty("change")
private Field change;
@JsonProperty("impliedVolatility")
private Field impliedVolatility;
@JsonProperty("ask")
private Field ask;
@JsonProperty("bid")
private Field bid;
@JsonProperty("lastPrice")
private Field lastPrice;
@JsonProperty("volume")
private LongFormatField volume;
@JsonProperty("lastTradeDate")
private LongFormatField lastTradeDate;
@JsonProperty("expiration")
private LongFormatField expiration;
@JsonProperty("openInterest")
private LongFormatField openInterest;
}
我正在尝试获取这样的数据...
List<Option> res = JSON_MAPPER.readValue(new URL(link), new TypeReference<List<Option>>() {});
for(Option o: res){
o.type = Option.Type.CALL;
System.out.println(o.toString());
}
Aa,这是个例外...
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token
at [Source: https://query2.finance.yahoo.com/v7/finance/options/AEIS?formatted=true&lang=en-US®ion=US&corsDomain=finance.yahoo.com; line: 1, column: 16] (through reference chain: java.util.HashMap["optionChain"])
问题是源中的 json return 以对象 属性、"optionChain" 开头,杰克逊试图将其反序列化为 HashMap
,但你期望在反序列化后得到一个 List
。
正如你提到的,你只需要 json 中的 "calls" 和 "puts",你可以使用 ObjectMapper.readTree
先得到整个 JsonNode
,然后通过JsonNode.findValue
找到"calls"的节点,最后反序列化该节点。下面是一个例子:
String link = "https://query2.finance.yahoo" +
".com/v7/finance/options/AEIS?formatted=true&lang=en-US®ion=US&corsDomain=finance.yahoo.com";
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(new URL(link));
JsonNode calls = jsonNode.findValue("calls");
List<Option> callOptions = mapper.readValue(calls.traverse(), new TypeReference<List<Option>>() {});