2016-11-29 247 views
4

我試圖將來自Cucumber的Json輸出轉換爲單個Java對象。這包含嵌套深度四級的對象,並且我有麻煩反序列化它。我目前正在使用傑克遜,但願意提供建議。 這是我的JSON代碼:將複雜的JSON反序列化爲Java,深層嵌套多個級別

{ 
"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註釋將它們放在單獨的類中。在此處,這讓我(省略制定者):

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(); 
    } 

是否有一個快速修復這種方法,使其工作,還是應該我嘗試完全不同的東西?

+0

你有沒有嘗試添加getter和setter方法?這些字段是不公開的,因此對象不能被序列化到這些類中 –

+1

我認爲只需要setter?我確實有這些,爲了使代碼更具可讀性,這裏省略。 – KeizerHarm

+0

@TurbutAlin恐怕,添加吸氣劑沒有任何效果。 – KeizerHarm

回答

2

好的,我花了一些時間調試,並試圖找出問題所在,最後是非常明顯的。

implements Serializable 

這就是我添加到MatchObject並工作的行。

當我們嘗試反序列化某個對象首先我們必須使這些類實現了接口Serializable接口

+0

這讓我取得了一些實際進展,謝謝!但我現在有一個新的錯誤:「java.lang.NoSuchMethodError:com.fasterxml.jackson.databind.JavaType.isReferenceType()Z」 – KeizerHarm

+0

@KeizerHarm可能你忘記了你的getter/setter或者你試圖反序列化的類型是錯誤的例如,將「hi」存儲爲整數屬性 – cralfaro

-1

你可以從這個代碼的想法反序列化,

public class testCustomDeSerializer extends JsonDeserializer<test> { 

public testCustomDeSerializer() { 
    this(null); 
} 

public TestCustomDeSerializer(Class t) { 
    // super(t); 
} 

@Override 
public Test deserialize(JsonParser p, DeserializationContext ctx) throws IOException, JsonProcessingException { 
    ObjectCodec objectCodec = p.getCodec(); 
    JsonNode node = objectCodec.readTree(p); 

    ObjectMapper objectMapper = new ObjectMapper(); 
    Test test= new Test(); 


    test.setId(node.get("line").asText()); 

    List<elements> elementList = new ArrayList<>(); 
    JsonNode elementsNode = node.get("elements"); 
    Iterator<JsonNode> slaidsIterator = elementsNode.elements(); 
    while (slaidsIterator.hasNext()) { 
     Steps steps= new Steps(); 
     JsonNode slaidNode = slaidsIterator.next(); 
     JsonNode stepNode= (JsonNode) slaidNode.get("Steps"); 
     BoundingPoly in = objectMapper.readValue(stepNode.toString(), Steps.class); 
     elementsNode.setSteps(in); 
     /// continue 

return 
     } 

希望它可以幫助

1

我只是想你的示例代碼和奇怪的是,它的工作原理。

如果JSON按照規定進入並且獲取者,制定者,構造函數實際存在,那麼您可以仔細檢查一下您的導入嗎?

+0

隨着包com.fasterxml.jackson不起作用 – cralfaro

+0

應該用this.var = var和所有實現構造函數嗎?我以爲他們應該是空的。 – KeizerHarm

+0

空或setters或完整的構造函數(設置所有字段) –