2016-07-02 11 views
1

Ich benutze jackson-datatype-guava. Ich versuche eine Tabelle aus JSON zu deserialisieren, aber ich bekomme eine Ausnahme.Deserialisieren von Guavas Tabelle mit Jackson-Würfen "JsonMappingException: Kein passender Konstruktor für Typ gefunden"

Mein Code ist:

@Test 
public void jsonTable() throws IOException { 
    Table<String, String, String> table = HashBasedTable.create(); 
    table.put("row1", "col1", "cell11"); 
    table.put("row1", "col2", "cell12"); 
    table.put("row2", "col1", "cell21"); 
    table.put("row2", "col2", "cell22"); 

    ObjectMapper mapper = new ObjectMapper() 
      .registerModule(new GuavaModule()); 

    String tableJson = mapper.writeValueAsString(table); 
    System.out.println(tableJson); 

    Table<String, String, String> deserializedTable = mapper.readValue(tableJson, HashBasedTable.class); 
} 

Die Ausnahme in der letzten Zeile geworfen ist:

com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class com.google.common.collect.HashBasedTable]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?) 
at [Source: {"row1":{"col2":"cell12","col1":"cell11"},"row2":{"col2":"cell22","col1":"cell21"}}; line: 1, column: 2] 
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:255) 
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1130) 
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:298) 
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:133) 
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3807) 
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2797) 
    at com.gk.dfm.repository.impl.JsonTableTest.jsonTable(JsonTableTest.java:31) 

Es macht Sinn, da HashBasedTable keinen Default-Konstruktor hat. Wir sollten es mit HashBasedTable.create() konstruieren. Wie kann ich es Jackson sagen?

Auf this page fand ich, wie Guava der Multimap deserialisieren:

@Test 
public void convert() throws JsonParseException, JsonMappingException, 
     JsonProcessingException, IOException { 

    ObjectMapper objectMapper = new ObjectMapper(); 
    objectMapper.registerModule(new GuavaModule()); 

    Multimap<String, NavItem> navs = objectMapper.readValue(
      objectMapper.treeAsTokens(objectMapper.readTree(jsonString)), 
      objectMapper.getTypeFactory().constructMapLikeType(
        Multimap.class, String.class, NavItem.class)); 

    logger.info(navs); 

    assertThat(navs.keys(), hasItems("123455", "999999")); 
} 

Wie kann ich es auf eine Tabelle anwenden? ConstructTableLikeType gibt es nicht.

Antwort

2

Zuerst versuchen Sie es mit jackson-datatypes-collections statt jackson-Datentyp-Guave, weil it has been moved under jackson-datatype-collections to simplify management, release process.

Die Unterstützung für Guava des Table scheint unvollständig zu sein, weil es an open issue for adding (de)serializer for it ist. Da es Open Source ist, können Sie es selbst tun (bitte zurückzahlen, wenn Sie dies tun!) - Sie können verwenden, was andere andere geschrieben haben, wie this pull request in old repository (auch see test for Table, die angibt, Serialisierung wird unterstützt, aber keine Deserialisierung obwohl).

+0

Vielen Dank. Ich denke, ich werde nur 'Tabelle ' in eine 'Map >' konvertieren und dann serialisieren/deserialisieren. Übrigens sollte die Dokumentation von jackson-datatypes-collections den Status der Unterstützung jeder Sammlung in den Bibliotheken erwähnen (besonders, wenn es halb fertig ist - es ist sehr irreführend). –