(Джексон 1.9.2) Получение @JsonIgnore для работы: десериализация с аннотациями примесей и полиморфными типами

Я пытаюсь десериализовать строку JSON, например (извлек этот бит, чтобы показать проблему)

{
    "$type": "com.example.StringProperty",
    "value": "hello world",
    "name": "text",
    "readOnly": false
}

в иерархию классов, которые выглядят как

public class Property
{
    public String name;
    public int    type;

    Property(String pName, int pType) { name = pName; type = pType; }
}

public class StringProperty extends Property 
{
    public String value;        
    StringProperty(String pName, String pValue) {
        super(pName, String);
        value = pValue;
    }       
}

используя следующие аннотации миксина

@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="$type")
abstract public class PropertyMixin
{
    @JsonProperty
    public String name;
    //@JsonIgnore
    //public boolean readOnly;
    @JsonProperty
    public int type;

    PropertyMixin(@JsonProperty("name") String pName, @JsonProperty("type") int pType)
    {
    }
}

abstract public class StringPropertyMixin
{
    @JsonProperty
    public String value;
    //@JsonIgnore
    //public boolean readOnly;

    @JsonCreator
    public StringPropertyMixin(@JsonProperty("name") String pName, @JsonProperty("value") String value)
    {
    }
}

С Jackson 1.9.2 ошибка, которую я получаю,

Unrecognized field "readOnly" (Class com.example.StringProperty), not marked as ignorable

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

Вот как выглядит среда десериализации:

        objectMapper.setVisibilityChecker(objectMapper.getSerializationConfig().getDefaultVisibilityChecker()
                .withFieldVisibility(JsonAutoDetect.Visibility.NONE)
                .withGetterVisibility(JsonAutoDetect.Visibility.NONE)
                .withSetterVisibility(JsonAutoDetect.Visibility.NONE)
                .withCreatorVisibility(JsonAutoDetect.Visibility.NONE));

        MixinRegistrations module = new MixinRegistrations();
        objectMapper.registerModule(module);

и модуль миксина выглядит так

@Override
public void setupModule(SetupContext context)
{
    context.setMixInAnnotations(Property.class, PropertyMixin.class);
    context.setMixInAnnotations(StringProperty.class, StringPropertyMixin.class);
}

Я ценю всю помощь. Заранее спасибо.

PS: я не знаю, имеет ли это значение, но JSON создается библиотекой, написанной на .Net Framework v4.


person alokoko    schedule 07.12.2011    source источник


Ответы (3)


Я считаю, что у Джексона проблемы, потому что метод, который вы делегировали как создатель, не имеет параметра для поля readOnly. Таким образом, вместо того, чтобы молча игнорировать этот отсутствующий параметр, Джексон выдает ошибку (хорошее поведение). Попробуйте использовать аннотацию JsonIgnoreProperties. У меня не было необходимости использовать if раньше, но для десериализации вы можете явно указать поля, которые не требуются создателю.

О, это тоже похоже.

Изменить: Еще один вопрос, нашел, что это было полезно.

person Dunes    schedule 07.12.2011
comment
Да, вы можете добавить @JsonIgnoreProperties(ignoreUnknown = true), если вам нужно такое поведение. - person Alejandro Diaz; 08.12.2011
comment
@Dunes: Как @JsonIgnoreProperties поможет, если @JsonIgnore не работает в этой ситуации? Похоже, что @JsonIgnoreProperties просто расширение @JsonIgnore для нескольких значений. - person alokoko; 08.12.2011
comment
Я понял, почему @JsonIgnore не работал в моем случае, но @JsonIgnoreProperties работает нормально после прочтения этот пост. Спасибо за указание на аннотацию @JsonIgnoreProperties. - person alokoko; 08.12.2011
comment
@alokoko Разница в том, что @JsonIgnoreProperties добавляется на уровне класса и может использоваться для игнорирования свойств JSON по имени; тогда как @JsonIgnore игнорирует только определенное свойство, и у вас должно быть поле или установщик/получатель, к которому его можно прикрепить. - person StaxMan; 08.12.2011
comment
@StaxMan: важна часть, и у вас должно быть поле или установщик / получатель, к которому ее можно прикрепить. Что я также упустил изначально, так это то, что этот оператор должен читаться как и у вас должно быть поле или сеттер/геттер для его присоединения в целевом классе, поскольку у меня уже было это поле в моем классе миксинов, но это не сработало. Я получил это после прочтения другого ответа от вас в другом сообщении. - person alokoko; 08.12.2011
comment
@alokoko Рад, что вы смогли найти решение. Добавлю ссылки в ответ. - person Dunes; 08.12.2011

Обратите внимание, что ваша проблема НЕ в том, что у класса есть свойство, которое Джексон не распознает, а в том, что у JSON есть свойство. Поэтому вы можете прочитать эту вики-страницу.

Как уже упоминалось, здесь будет работать @JsonIgnoreProperties, поскольку добавление этой аннотации к классу не требует поля или сеттера, в отличие от @JsonIgnore. Кроме того, его можно использовать для игнорирования любых неизвестных свойств.

person StaxMan    schedule 08.12.2011
comment
Спасибо за ссылку. За 30 секунд до вашего ответа я написал комментарий о том, как я понял, как все работает. :-) - person alokoko; 08.12.2011

@JsonIgnoreProperties({"propX", "propY"})

Будет работать просто отлично на уровне класса!

person Nisarg Panchal    schedule 25.05.2015