2011-06-16 5 views
25

У меня есть объект домена, который имеет карту:Не удается найти (карта) Key десериализатор для типа [простой тип, класс com.comcast.ivr.core.domain.AutoHandlingSlotKey]

private Map<AutoHandlingSlotKey, LinkedHashSet<AutoFunction>> autoHandling; 

Когда я сериализовать объект, я получаю это:

"autoHandling" : [ "java.util.HashMap", { 
} ], 

ключ эта карта является пользовательский объект:

public class AutoHandlingSlotKey implements Serializable { 
    private FunctionalArea slot; // ENUM 
    private String returnView; // ENUM 

Итак, я не знаю, как исправить эту проблему я продолжать получать, когда я десериализации объекта:

org.codehaus.jackson.map.JsonMappingException: Can not find a (Map) Key deserializer for type [simple type, class com.comcast.ivr.core.domain.AutoHandlingSlotKey] 

Может кто-то помочь мне понять, как исправить эту проблему, если я НЕ иметь доступ к объекту домена изменить?

ответ

16

По умолчанию Джексон пытается сериализовать Java-карты как объекты JSON (пары ключ/значение), поэтому объект-ключ карты должен каким-то образом сериализоваться как строка; и должен быть соответствующий (и зарегистрированный) десериализатор ключей. Конфигурация по умолчанию поддерживает только небольшой набор типов JDK (String, numbers, enum). Так что картограф не имеет понятия, как взять строку и создать из нее AutoHandlingSlotKey. (на самом деле я удивлен, что сериализатору не преминул по той же причине)

Два очевидных пути решения этого:

  • Осуществить и зарегистрировать «ключ десериализатор»
  • Осуществить и зарегистрировать пользовательские десериализатор для карт.

В вашем случае, вероятно, легче сделать прежний. Вы также можете реализовать собственный сериализатор ключей, чтобы гарантировать, что ключи являются сериализаторами в правильном формате.

Самый простой способ регистрации сериализаторов и десериализаторов - Module interface, который был добавлен в Jackson 1.7 (и расширен в 1.8 для поддержки сериализаторов/десериализаторов ключей).

+0

После быстрого теста, я думаю, что ключи сериализуются с использованием метода toString, который, вероятно, часто не то, что вы хотите. Создание ключевого сериализатора кажется хорошим вариантом. – Suma

+0

Это резерв, если ничего не найдено. Существуют альтернативы: если тип имеет публичный конструктор с одним строковым аргументом, например, который будет использоваться. Или метод фабрики с одним строковым аргументом, который аннотируется с помощью '@ JsonCreator'.Это устранит необходимость записи и регистрации настраиваемого десериализатора ключей. – StaxMan

+0

Отлично, но вы описываете десериализатор (я попробую это). Как насчет сериализатора? В моем случае использовался toString (для класса case Scala). Какие еще существуют опции для сериализатора, помимо написания моего собственного? – Suma

8

Это предложение было задано давно, и это первый результат Google при поиске ошибки, но принятый ответ не имеет кода и может быть запутанным для начинающего джексона (меня). В итоге я нашел this answer, который помог.

Итак, как указано в принятом ответе, Реализация и регистрация «ключевого десериализатора» - это путь. Вы можете сделать это вот так.

SimpleModule simpleModule = new SimpleModule(); 
simpleModule.addKeyDeserializer(YourClass.class, new YourClassKeyDeserializer()); 
objectMapper.registerModule(simpleModule); 

А для класса, все, что вам нужно сделать, это:

class YourClassKeyDeserializer extends KeyDeserializer 
{ 
    @Override 
    public Object deserializeKey(final String key, final DeserializationContext ctxt) throws IOException, JsonProcessingException 
    { 
     return null; // replace null with your logic 
    } 
} 

Вот так! Никакой аннотации на классы, а не пользовательский десериализатор для карт и т. Д.

Смежные вопросы