2016-07-25 6 views
0

Я пытаюсь реализовать собственный десериализатор, используя StdDeserializer<T>. В моем методе deserialize(JsonParser, DeserializationContext) я пытаюсь использовать JsonParser, чтобы прочитать Multimap, учитывая, что строка JSON равна { "toMap": { "a": "b", "a": "c" } }.Jackson JsonParser readValueAs Multimap

Предполагая, что я нахожусь в точке, где имя поля "toMap", я попытался сделать это: Multimap<String, Object> rawConditions = jsonParser.readValuesAs(new TypeReference<LinkedListMultimap<String, Object>>() {});, но это приводит к ошибке компиляции. В нем говорится, что у них есть несовместимые типы - требуется Multimap<String, Object>, но он находит Iterator<Object>.

+0

Не могли бы вы быть более конкретными и написать, что должно быть в вашем «Multimap» после разбора вашего примера ввода? – Xaerxess

+0

Я добавил ответ. Но если у вас есть контроль над сериализацией, было бы лучше иметь {"a": ["b", "c"]}, а не {"a": "b", "a": "c" } – Joel

ответ

0

гуава-х Multimap<K, V> примерно эквивалентен Map<K, Collection<V>>, но в ваших данных ({ "toMap": { "a": "b", "a": "c" } }) вы Map<K, Map<V, X>>, которые, конечно, не можете быть десериализованными к Multimap. Если вы настаиваете на использовании Guava, вы можете десериализовать его до Table. Конечно, я предполагаю, что вы используете jackson-datatypes-collections и имеете GuavaModule, зарегистрированный в ObjectMapper.

EDIT: Если вы хотите десериализацию "toMap" значения в Multimap (т.е. { "a": "b", "a": "c" }), она также не является действительным Multimap<K, V> (или Map<K, Collection<V>>, если вы хотите), а Map<K, V>:

  • он имеет дублирующий ключ "a",
  • он должен быть чем-то вроде { "a": ["b"], "x": ["c"] } действительным Multimap.

Попробуйте десериализовать его как Map<String, String>.

+0

За исключением того, что клавиша «a» дублируется, поэтому ее можно интерпретировать как мультимап. – Joel

+0

@Joel Если OP хочет, чтобы '' toMap ''** значение ** обрабатывалось, оно также не является допустимым' Multimap '(или' Map > ', если вы хотите), а скорее' Map ' , – Xaerxess

+0

Не думайте так. {"a": "b", "a": "c"} можно интерпретировать как {"a": ["b", "c"]}, который, вы согласитесь, одобрен как мультимап. Данные - это просто данные. Вы можете интерпретировать его так, как хотите. – Joel

0

Я не знаю ни одного встроенного преобразователя для multimaps, но предполагая, что Multimap вы ищете в вашем примере { "a": "b", "a": "c" } (без «toMap»), и что вы ожидаете, что переводится как что-то вроде {"a": ["b", "c"]}, вы может написать собственный десериализатор, разыгрывая токен json токеном и добавляя его к вашему мультимапу. Пример:

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; 
    } 
} 
Смежные вопросы