java - 将复杂的 JSON 反序列化为 Java,类嵌套多层

标签 java json jackson inner-classes json-deserialization

我正在尝试将 Cucumber 的 Json 输出转换为单个 Java 对象。这包含嵌套了四层深的对象,我在反序列化时遇到了麻烦。我目前正在使用 Jackson,但愿意接受建议。 这是我的 Json 代码:

{
"line": 1,
"elements": [
  {
    "line": 3,
    "name": "Converteren centimeters naar voeten/inches",
    "description": "",
    "id": "applicatie-neemt-maten-in-cm-en-converteert-ze-naar-voet/inch,-en-vice-versa;converteren-centimeters-naar-voeten/inches",
    "type": "scenario",
    "keyword": "Scenario",
    "steps": [
      {
        "result": {
          "duration": 476796588,
          "status": "passed"
        },
        "line": 4,
        "name": "maak Maten-object aan met invoer in \"centimeters\"",
        "match": {
          "arguments": [
            {
              "val": "centimeters",
              "offset": 37
            }
          ],
          "location": "StepDefinition.maakMatenObjectAanMetInvoerIn(String)"
        },
        "keyword": "Given "
      },
      {
        "result": {
          "duration": 36319,
          "status": "passed"
        },
        "line": 5,
        "name": "ik converteer",
        "match": {
          "location": "StepDefinition.converteerMaten()"
        },
        "keyword": "When "
      },
      {
        "result": {
          "duration": 49138,
          "status": "passed"
        },
        "line": 6,
        "name": "uitvoer bevat maat in \"voeten/inches\"",
        "match": {
          "arguments": [
            {
              "val": "voeten/inches",
              "offset": 23
            }
          ],
          "location": "StepDefinition.uitvoerBevatMaatIn(String)"
        },
        "keyword": "Then "
      }
    ]
  },
  {
    "line": 8,
    "name": "Converteren voeten/inches naar centimeters",
    "description": "",
    "id": "applicatie-neemt-maten-in-cm-en-converteert-ze-naar-voet/inch,-en-vice-versa;converteren-voeten/inches-naar-centimeters",
    "type": "scenario",
    "keyword": "Scenario",
    "steps": [
      {
        "result": {
          "duration": 84175,
          "status": "passed"
        },
        "line": 9,
        "name": "maak Maten-object aan met invoer in \"voeten/inches\"",
        "match": {
          "arguments": [
            {
              "val": "voeten/inches",
              "offset": 37
            }
          ],
          "location": "StepDefinition.maakMatenObjectAanMetInvoerIn(String)"
        },
        "keyword": "Given "
      },
      {
        "result": {
          "duration": 23928,
          "status": "passed"
        },
        "line": 10,
        "name": "ik converteer",
        "match": {
          "location": "StepDefinition.converteerMaten()"
        },
        "keyword": "When "
      },
      {
        "result": {
          "duration": 55547,
          "status": "passed"
        },
        "line": 11,
        "name": "uitvoer bevat maat in \"centimeters\"",
        "match": {
          "arguments": [
            {
              "val": "centimeters",
              "offset": 23
            }
          ],
          "location": "StepDefinition.uitvoerBevatMaatIn(String)"
        },
        "keyword": "Then "
      }
    ]
  }
],
"name": "Applicatie neemt maten in cm en converteert ze naar voet/inch, en vice versa",
"description": "",
"id": "applicatie-neemt-maten-in-cm-en-converteert-ze-naar-voet/inch,-en-vice-versa",
"keyword": "Feature",
"uri": "sample.feature"
}

我尝试了多种不同的方法。首先,我使用了嵌套的内部类,但看起来您必须将它们设为静态,我担心这行不通,因为我在一个对象中有多个相同对象的实例(例如,根中有多个“元素”对象)。然后我尝试将它们放在单独的类中,并带有 Json 注释。这就是我的灵感所在(省略 setter):

public class CucumberUitvoer {
    private String name;
    private String description;
    private String id;
    private String keyword;
    private String uri;
    private int line;
    @JsonProperty("elements")
    private List<FeatureObject> elements;

    public CucumberUitvoer(){}
}

public class FeatureObject {
    private String name;
    private String description;
    private String id;
    private String type;
    private String keyword;
    private int line;
    @JsonProperty("steps")
    private List<StepObject> steps;

    public FeatureObject() {
    }
}

public class StepObject {
    @JsonProperty("result")
    private ResultObject result;
    private String name;
    private String given;
    private String location;
    private String keyword;
    private int line;
    @JsonProperty("match")
    private MatchObject match;

    public StepObject(){}
}

public class ResultObject {
    private int duration;
    private String status;

    public ResultObject(){}
}

public class MatchObject {
    @JsonProperty("arguments")
    private List<ArgumentObject> arguments;
    private String location;

    public MatchObject(){}
}

public class ArgumentObject {
    private String val;
    private String offset;

    public ArgumentObject(){}
}

为了澄清,here是嵌套如何工作的类图。

这个解决方案给我以下错误:

com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of nl.icaprojecten.TestIntegratieQuintor.JSONInterpreter.CucumberUitvoer out of START_ARRAY token

这是执行实际映射的代码:

ObjectMapper mapper = new ObjectMapper();
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    CucumberUitvoer obj1 = null;
    try {
        obj1 = mapper.readValue(json, CucumberUitvoer.class);
    } catch (IOException e) {
        e.printStackTrace();
    }

是否可以快速修复此方法以使其发挥作用,还是我应该尝试一些完全不同的方法?

最佳答案

好吧,我花了一些时间调试并试图找出问题所在,最后发现了一些非常明显的问题。

implements Serializable

这就是我添加到 MatchObject 并起作用的行。

当我们首先尝试反序列化某个对象时,我们必须让这些类实现接口(interface) Serializable

关于java - 将复杂的 JSON 反序列化为 Java,类嵌套多层,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40862477/

相关文章:

java - 如何在Java中使用反射(不使用抽象处理器或APT)处理源级注释?

java - 分派(dispatch)到 View 时,如何停止使用 Spring 处理程序中的命令对象隐式丰富模型?

Java:生成 JSON:尝试命名对象和数组时出现异常

php - JSON:从另一个域检索 JSON 文件

java - 自定义 Jackson HttpMessageConverter 在 Spring 4.2 中不再有效

jackson - Dropwizard隐藏json字段

Java Jackson 反序列化功能

java - 我不断收到 "OAuth consumer key/secret combination not supplied"错误消息

java - 读取多个Excel表格

java - Jackson 数据绑定(bind)与异构 Json 对象