杰克逊:忽略属性而不是抛出JsonMappingException

时间:2012-01-11 22:51:04

标签: java json jackson

我有一个需要使用Jackson从JSON反序列化的类。类结构如下所示:

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 个答案:

答案 0 :(得分:2)

我已经弄清楚自定义反序列化器不起作用的原因:readValueAs方法使用{,这会触发异常,将}作为下一个标记。这会关闭内部对象,然后解析器会认为接下来遇到的枚举值需要解析为内部类型,而不是枚举类型。

明天我会试试这个,但我认为应该采用deserialize方法:

ObjectMapper om = ...;

JsonNode node = arg0.readValueAs(JsonNode.class);
try
{
    return om.readValue(node, new TypeReference<List<C>>(){});
}
catch (JsonMappingException jme)
{
}
return null;