Джексон: игнорирование свойств вместо выбрасывания JsonMappingException - PullRequest
5 голосов
/ 12 января 2012

У меня есть класс, который нужно десериализовать из JSON с использованием Jackson.Структура класса выглядит следующим образом:

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;
}

Десериализация объектов в основном работает нормально; кроме , он взаимодействует с ошибочным кодом, который выдал неправильное значение, когда список был пуст.То есть вместо испускания:

{ "b" : { "c" : [] } }

он испустил:

{ "b" : { "c" : {} } }

Джексон выдает это исключение, когда сталкивается с этим:

org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token
 at [Source: [B@1ad5cabc; 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"])

Обратите внимание, что это исключение только происходит, если я пытаюсь десериализоватьвнешний тип A - если я извлекаю внутреннее сериализованное значение для B и десериализую его, он работает нормально.

1 Ответ

2 голосов
/ 12 января 2012

Я выяснил, почему пользовательский десериализатор не работает: метод readValueAs использует {, который вызывает исключение, оставляя } в качестве следующего токена. Это закрывает внутренний объект, и анализатор тогда думает, что значение перечисления, с которым встречаются в следующий раз, должно быть проанализировано как внутренний тип, а не как тип перечисления.

Я попробую это завтра, но я думаю, что путь будет в методе deserialize:

ObjectMapper om = ...;

JsonNode node = arg0.readValueAs(JsonNode.class);
try
{
    return om.readValue(node, new TypeReference<List<C>>(){});
}
catch (JsonMappingException jme)
{
}
return null;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...