【发布时间】:2017-07-19 18:46:10
【问题描述】:
我需要在 Java 1.7 中使用 Jackson 反序列化这个,使用货币作为值:
"prices": {
"USD": [
[1, "1.99000"],
[100, "1.89000"],
[1000, "1.40500"]
],
"EUR": [
[1, "1.53000"],
[100, "1.45000"],
[1000, "1.08350"]
]
}
(来源是这个 REST API https://octopart.com/api/docs/v3/rest-api#notes-partoffer.prices)
我的目标是为每个 Price 获取具有货币、价格中断和价格属性的对象。
我不知道该怎么做。我尝试了以下方法:
-
将整个“价格”反序列化为字符串以供进一步处理(不起作用,无法从 START_OBJECT 令牌中反序列化 java.lang.String 的实例 - 显然,因为这是 JSON_OBJECT)
-
反序列化
LinkedHashMap<String, LinkedHashMap<Integer, String>>>
(受此 Deserializing Jackson by using a key as value 启发,但也没有用)
-
使用这样的包装器:
public class PartOfferPriceWrapper { private LinkedHashMap<String, List<Entry<Integer, String>>> prices; }
然后处理如下:
List<PartOfferPrice> partOfferPriceList = new ArrayList<PartOfferPrice>();
for (Entry<String, List<Entry<Integer, String>>> currencyEntry :
partOfferPrices.entrySet()) {
for (Entry<Integer, String> priceEntry : currencyEntry.getValue()) {
PartOfferPrice partOfferPrice = new PartOfferPrice();
partOfferPrice.setOffer_id(partOfferId);
partOfferPrice.setCurrency(currencyEntry.getKey());
partOfferPrice.setPriceBreak(priceEntry.getKey());
partOfferPrice.setPrice(Double.parseDouble(priceEntry.getValue()));
partOfferPriceList.add(partOfferPrice);
}
这看起来不错,但结果是空的(这是更大响应的一部分,使用 Response.readEntity 读取成功)。我找不到任何其他方法来处理这个(一些自定义反序列化器?)。
编辑
我尝试按照 tima 的建议使用自定义反序列化器:
public class PartOfferPricesWrapperDeserializer extends
JsonDeserializer<PartOfferPricesWrapper> {
public PartOfferPricesWrapperDeserializer() { super(); }
@Override
public PartOfferPricesWrapper deserialize(JsonParser jsonParser,
DeserializationContext context) throws IOException,
JsonProcessingException {
PartOfferPricesWrapper partOfferPricesWrapper = new
PartOfferPricesWrapper();
List<PartOfferPrice> priceList = new ArrayList<PartOfferPrice>();
JsonNode node = jsonParser.readValueAsTree();
Iterator<Entry<String, JsonNode>> nodes =
node.get("prices").fields();
while (nodes.hasNext()) {
Map.Entry<String, JsonNode> entry = nodes.next();
for (JsonNode tempNode : entry.getValue()) {
PartOfferPrice price = new PartOfferPrice();
price.setCurrency(entry.getKey());
for (int i = 0; i < tempNode.size(); i++) {
if (tempNode.get(i).isInt()) {
price.setPriceBreak(tempNode.get(i).intValue());
}
else
{
price.setPrice(tempNode.get(i).asDouble());
}
}
priceList.add(price);
}
}
partOfferPricesWrapper.setPrices(priceList);
return partOfferPricesWrapper;
}
}
将此添加到处理程序方法中:
SimpleModule module = new SimpleModule();
module.addDeserializer(PartOfferPricesWrapper.class, new
PartOfferPricesWrapperDeserializer());
objectMapper.registerModule(module);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,
false);
partsMatchResponse = objectMapper.readValue(target.getUri().toURL(),
PartsMatchResponse.class);
如果响应仅包含“价格”节点,这可能会起作用,但现在我在 node.get(“价格”).fields() 上得到 NullPointerException;它可能试图解析整个响应,但我只需要对“价格”部分使用自定义反序列化器。有可能吗?
非常感谢。
【问题讨论】:
标签: java json key-value json-deserialization