У меня есть класс, который нужно десериализовать из JSON с помощью Jackson. Структура классов выглядит так:Джексон: игнорирование свойств вместо того, чтобы бросать JsonMappingException
public class A {
public B b;
}
public class B {
public List<C> c;
}
public class C {
public String s;
public Long l1;
public Long l2;
public Long l3;
}
Deserializing объекты в основном работают нормально; кроме, он взаимодействует с кодом ошибки, который испускает неправильное значение, когда список пуст. То есть, вместо того, чтобы испускать:
{ "b" : { "c" : [] } }
он излучается:
{ "b" : { "c" : {} } }
Джексон бросает это исключение, когда сталкивается с этим:
org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token
at [Source: [[email protected]; line: 1, column: 896] (through reference chain: A["b"]->B["c"])
Все это имеет смысл, конечно. Вход неверный.
Однако, пустой список в этом случае не относится ни к одному из кодов; если это было null
Мне было все равно. Есть ли способ сказать Джексону игнорировать это свойство (и хранить null
), если его десериализировать невозможно?
Я попытался с помощью пользовательского десериализатор:
public class CListDeserializer extends JsonDeserializer<List<C>>
{
public CListDeserializer() { }
@Override
public List<C> deserialize(JsonParser arg0,
DeserializationContext arg1) throws IOException,
JsonProcessingException
{
try
{
return arg0.readValueAs(new TypeReference<List<C>>(){});
}
catch (JsonMappingException jme)
{
}
return null;
}
}
А если добавить аннотацию к полю:
@JsonDeserialize(using=CListDeserializer.class)
public List<C> c;
я получаю это исключение вместо:
org.codehaus.jackson.map.JsonMappingException: Can not instantiate value of type [simple type, class asgard.ChangeEntry] from JSON String; no single-String constructor/factory method (through reference chain: A["b"])
Обратите внимание, что это исключение только происходит, если я попытаюсь десериализовать t он внешний тип A
- если я вытащил внутреннее сериализованное значение для B
и десериализую это, он отлично работает.
Еще одна точка данных: класс B также имеет поле перечислимую, который имеет такое же имя как ссылка на 'B' в' A': 'public EnumType b'. Когда Джексон делает десериализацию внутреннего типа «B», он, похоже, запутывается и пытается десериализовать его как «A» –