Джексон - игнорировать суперкласс Map при сериализации - PullRequest
4 голосов
/ 04 января 2012

У меня есть несколько классов моделей, которые расширяют LinkedHashMap<String, Object>: они определяют геттеры и сеттеры, которые обертывают методы get и put карты. Я пытаюсь сериализовать экземпляры этих классов, используя Джексона (с RESTEasy), но Джексон отказывается обращать внимание на мои геттеры, которые отмечены @JsonProperty. Вместо этого он только сериализует пары ключ-значение на вспомогательной карте. Я попытался использовать @JsonAutoDetect, чтобы отключить автоопределение для всех методов и полей, но это ничего не изменило. Есть ли способ предотвратить автоматическую сериализацию карты Джексоном, или я должен создать новые классы моделей, которые не расширяются LinkedHashMap<String, Object>?

Ответы [ 3 ]

9 голосов
/ 04 января 2012

Я согласен с ответом @ skaffman. Но если вы не можете легко изменить структуру наследования, возможно, есть способы обойти это.

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

@JsonSerialize(as=MyInterface.class)
@JsonDeserialize(as=MyInterface.class)

, что заставит Джексона использовать только то, что доступно через определенный интерфейс.

Также возможны пользовательские сериализаторы / десериализаторы, но это совсем немного работы.

7 голосов
/ 04 января 2012

У меня есть несколько классов моделей, которые расширяют LinkedHashMap<String, Object>: они определяют геттеры и сеттеры, которые обертывают методы get и put карты

Это классический пример, когда не использует наследование: вы обнаружите, что какой-то другой фрагмент кода (например, Джексон) рассматривает ваш класс как экземпляр его суперкласса, который что ты хочешь это сделать. В подобных случаях (а также в целом) обычно лучше использовать композицию, а не наследование.

Я рекомендую переписать класс вашей модели, чтобы содержал карту, а не расширять ее. Вы получаете гораздо больше контроля, чем способ, и полученная модель менее хрупкая. Если вам нужно рассматривать вашу модель как Map, то реализуйте метод asMap (или что-то подобное), который отображает это представление.

2 голосов
/ 12 мая 2015

Вы можете реализовать свой собственный org.codehaus.jackson.map.DeserializerProvider, который расширяет org.codehaus.jackson.map.deser.StdDeserializerProvider Джексона и метод перезаписи _createDeserializer:

import org.codehaus.jackson.map.SerializerProvider;
import org.codehaus.jackson.map.deser.StdDeserializerProvider;
import org.codehaus.jackson.map.DeserializationConfig;
...

class MyDeserializerProvider extends StdDeserializerProvider {

    @Override
    protected JsonDeserializer<Object> _createDeserializer(DeserializationConfig config, JavaType type, BeanProperty property) throws JsonMappingException {
        if (type.isMapLikeType()) {       // (1)
            return this._factory.createBeanDeserializer(config, this, type, property);
        } else {
            return super._createDeserializer(config, type, property);
        }
    }
}

(1) использовать условие if, которое соответствует вашим потребностям

Пользовательский десериализатор зарегистрирован непосредственно в ObjectMapper:

ObjectMapper om = new ObjectMapper();
om.setDeserializerProvider(new MyDeserializerProvider());

Я проверял это с Джексоном 1.9.11.

...