2016-07-25 13 views
0

Ich versuche, einen benutzerdefinierten Deserializer mit StdDeserializer<T> zu implementieren. In meiner deserialize(JsonParser, DeserializationContext) Methode versuche ich JsonParser zu verwenden, um eine Multimap zu lesen, da die JSON-Zeichenfolge { "toMap": { "a": "b", "a": "c" } } ist.Jackson JsonParser readValueAs Multimap

Angenommen, ich bin an einem Punkt, wo der Feldname "toMap" ist, habe ich versucht, dies zu tun: Multimap<String, Object> rawConditions = jsonParser.readValuesAs(new TypeReference<LinkedListMultimap<String, Object>>() {});, aber es führt zu einem Kompilierungsfehler. Es heißt, sie haben inkompatible Typen - ein Multimap<String, Object> ist erforderlich, aber es findet einen Iterator<Object>.

+0

Können Sie genauer sein und schreiben, was in Ihrem 'Multimap' sein sollte, nachdem Sie Ihre Beispieleingabe analysiert haben? – Xaerxess

+0

Ich habe eine Antwort hinzugefügt. Aber wenn Sie auf der Serialisierungsseite Kontrolle haben, wäre es besser, {"a": ["b", "c"]} als {"a": "b", "a": "c" } – Joel

Antwort

0

Guava Multimap<K, V> das entspricht in etwa Map<K, Collection<V>> aber in Ihren Daten ({ "toMap": { "a": "b", "a": "c" } }) Sie haben Map<K, Map<V, X>>, die, natürlich, nicht zu Multimap deserialisiert werden. Wenn Sie darauf bestehen, Guava zu verwenden, können Sie es auf Table deserialisieren. Natürlich nehme ich an, Sie verwenden jackson-datatypes-collections und haben GuavaModule registriert in ObjectMapper.

EDIT: Wenn Sie "toMap" Wert als multimap (dh { "a": "b", "a": "c" }) deserialisieren möchten, es ist auch nicht gültig Multimap<K, V> (oder Map<K, Collection<V>> wenn Sie wollen), sondern Map<K, V>:

  • Es hat doppelten Schlüssel "a",
  • sollte es so etwas wie { "a": ["b"], "x": ["c"] } zu einem gültigen Multimap sein.

Versuchen Sie, es als Map<String, String> stattdessen zu deserialisieren.

+0

Mit der Ausnahme, dass der Schlüssel "a" dupliziert ist, so kann es als eine Multimap interpretiert werden. – Joel

+0

@Joel Wenn OP '' toMap "' ** value ** geparst werden soll, ist es auch kein gültiges 'Multimap '(oder' Map > 'wenn Sie wollen), sondern' Map ' . – Xaerxess

+0

Denke nicht so. {"a": "b", "a": "c"} könnte als {"a": ["b", "c"]} interpretiert werden, was, wie du zustimmst, als Multimap-Karte in Ordnung ist. Daten sind nur Daten. Sie können es so interpretieren, wie Sie es möchten. – Joel

0

Ich bin nicht bekannt, dass integrierten Konverter für multimaps, aber die multimap unter der Annahme in Ihrem Beispiel Sie suchen ist { "a": "b", "a": "c" } (ohne „toMap“), und dass man es übersetzt so etwas wie {"a": ["b", "c"]} erwarten Sie könnte Ihren eigenen Deserializer schreiben, indem Sie den JSON-Token nach Token analysieren und ihn Ihrer Multimap hinzufügen. Beispiel:

public class CustomDeserializer extends JsonDeserializer<Multimap<String, String>> { 

    @Override 
    public Multimap<String, String> deserialize(JsonParser jp, DeserializationContext dc) 
      throws IOException { 
     Multimap<String, String> multimap = LinkedListMultimap.create(); 
     JsonToken currentToken = null; 
     while ((currentToken = jp.nextValue()) != null) { 
      switch (currentToken) { 
       case VALUE_STRING: 
        multimap.put(jp.getCurrentName(), jp.getText()); 
        break; 
      } 
     } 
     return multimap; 
    } 
}