Java:使用Jackson帮助读取YAML中的关联数组

时间:2019-07-19 23:07:46

标签: java jackson yaml

如何使用Jackson来阅读Java下面的内容?

innings:
  - 1st innings:
      team: England
      deliveries:
        - 0.1:
            batsman: ME Trescothick
            bowler: DT Johnston
            non_striker: EC Joyce
            runs:
              batsman: 0
              extras: 0
              total: 0

我尝试了以下类结构,但它们都不起作用:

选项1:

public class Inning {
    public String team;
    public Map<String, Delivery> deliveries;
}
public Map<String,Inning> innings;

选项2: 我将Map<K,V>替换为List<V>

选项1给出:

java.lang.RuntimeException: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.LinkedHashMap` out of START_ARRAY token
 at [Source: (File); line: 30, column: 3] (through reference chain: cricket.CricSheet["innings"])
    at cricket.CricSheet.readFromFile(CricSheet.java:20)
CricSheet.java:20
    at cricket.App.main(App.java:12)
App.java:12
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.LinkedHashMap` out of START_ARRAY token
 at [Source: (File); line: 30, column: 3] (through reference chain: cricket.CricSheet["innings"])
    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
MismatchedInputException.java:63
    at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1343)
DeserializationContext.java:1343
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1139)
DeserializationContext.java:1139
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1093)
DeserializationContext.java:1093
    at com.fasterxml.jackson.databind.deser.std.StdDeserializer._deserializeFromEmpty(StdDeserializer.java:600)
StdDeserializer.java:600
    at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:360)
MapDeserializer.java:360
    at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:29)
MapDeserializer.java:29
    at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:138)
FieldProperty.java:138
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
BeanDeserializer.java:288
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
BeanDeserializer.java:151
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
ObjectMapper.java:4013
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2902)
ObjectMapper.java:2902
    at cricket.CricSheet.readFromFile(CricSheet.java:18)

选项2给出:

Exception in thread "main" java.lang.RuntimeException: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "1st innings" (class cricket.Inning), not marked as ignorable (2 known properties: "deliveries", "team"])
 at [Source: (File); line: 31, column: 7] (through reference chain: cricket.CricSheet["innings"]->java.util.ArrayList[0]->cricket.Inning["1st innings"])
    at cricket.CricSheet.readFromFile(CricSheet.java:20)
CricSheet.java:20
    at cricket.App.main(App.java:12)
App.java:12
Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "1st innings" (class cricket.Inning), not marked as ignorable (2 known properties: "deliveries", "team"])
 at [Source: (File); line: 31, column: 7] (through reference chain: cricket.CricSheet["innings"]->java.util.ArrayList[0]->cricket.Inning["1st innings"])
    at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61)
UnrecognizedPropertyException.java:61
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:823)
DeserializationContext.java:823

2 个答案:

答案 0 :(得分:2)

如果将YAML粘贴到在线YAML解析器中,例如,也许您可​​以更好地了解YAML结构。 https://yaml-online-parser.appspot.com/

它显示:

  

输出

     
{
  "innings": [
    {
      "1st innings": {
        "deliveries": [
          {
            "0.1": {
              "batsman": "ME Trescothick", 
              "bowler": "DT Johnston", 
              "runs": {
                "batsman": 0, 
                "total": 0, 
                "extras": 0
              }, 
              "non_striker": "EC Joyce"
            }
          }
        ], 
        "team": "England"
      }
    }
  ]
}

如您所见,根是Map<String, List<Map<String, Inning>>>,其中

  • 外部映射具有一个键为"innings"的条目,其值是:
    • 具有一个元素的数组:
      • 内部地图有一个条目,键为"1st innings",值:
        • 一个Inning对象

由于Inning具有字段teamdeliveries,所以确实映射到从第三个{开始的对象。

因此,外面有2个字符串:"innings""1st innings"。您的任何尝试都不允许使用两个名称,因此它们可能无法正常工作。

我将由您决定是否需要该额外地图的课程。我建议创建一个Game字段为innings的{​​{1}}类。 List<?>?还是某个带有Map<String, Inning>字段的类取决于您。

答案 1 :(得分:0)

注意自我。必须更改为:

public List<Map<String,Inning>> innings;

public class Inning {
    public String team;
    public List<Map<String, Delivery>> deliveries;
}