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

标签 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

最佳答案

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

它显示:

Output

{
  "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>>> ,其中

  • 外部 map 有一个带有键 "innings" 的条目,和值:
    • 只有一个元素的数组:
      • 内部 map 有一个带有键 "1st innings" 的条目,和值:
        • Inning对象

Inning有字段teamdeliveries ,它确实映射到从第三个 { 开始的对象.

所以外面有 2 个字符串:"innings""1st innings" 。您的两次尝试都不允许使用两个名称,因此它们不可能起作用。

我将让您决定是否需要为该额外 map 开设类(class)。我建议创建一个 Gameinnings字段是 List<?> 。是否?Map<String, Inning>或一些带有 "1st innings" 的类(class)领域由你决定。

关于Java:帮助使用 Jackson 读取 YAML 中的关联数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57120479/

相关文章:

java - 将BaseGameUtils添加到libgdx项目时出现问题

java - 为什么 jackson 这么慢?

java - 通过yaml配置java类对象列表

java - 如何仅将网站页面发送到默认浏览器并在 webview 中加载其余网站页面?

java - 我在 Netbeans 中有一个使用 JOptionPane.showOptionDialog 的游戏,但我不知道如何执行 if 语句

java - 当嵌套 JSON 中出现相同字段名称时,将 JSON 解析为 java 对象

java - 如何用 Jackson 反序列化将每个映射条目的键注入(inject)到相应的值对象中?

ios - Travis CI 的完整 Xcode 版本和设备名称/操作系统列表?

aws-lambda - 模板包含错误。: 模板错误:Fn::GetAtt 实例引用 api 网关中未定义的资源 LambdaInvokeFunction

java - 如何开发自己的 Java 库?