杰克逊:忽略属性而不是抛出JsonMappingException [英] Jackson: ignoring properties instead of throwing JsonMappingException

查看:82
本文介绍了杰克逊:忽略属性而不是抛出JsonMappingException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a class that needs to be deserialized from JSON using Jackson. The class structure looks like this:

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 objects mostly works fine; except, it is inter-operating with buggy code that emitted the wrong value when the list was empty. That is, instead of emitting:

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

它已经发出:

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

杰克逊抛出此异常遇到这个:

Jackson throws this exception when it encounters this:

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"])

当然,这一切都是有道理的。输入错误。

This all makes sense, of course. The input is wrong.

但是,在这种情况下,空列表与任何代码无关;如果它是 null 我不在乎。有没有办法告诉杰克逊忽略这个属性(并存储 null )如果无法反序列化它?

However, the empty list in this case isn't relevant to any of the code; if it was null I wouldn't care. Is there any way to tell Jackson to ignore this property (and store null) if it's not possible to deserialize it?

我尝试过使用自定义反序列化器:

I've tried using a custom deserializer:

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

如果我在字段中添加注释:

And if I add the annotation to the field:

@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 ,并反序列化,它工作正常。

Note that this exception only happens if I try deserializing the outer type A -- if I pull out the inner serialized value for B, and deserialize that, it works fine.

推荐答案

我已经找到了为什么定制反序列化器不起作用: readValueAs 方法使用 {,这会触发异常,留下} 作为下一个标记。这会关闭内部对象,然后解析器会认为接下来遇到的枚举值需要被解析为内部类型,而不是enum类型。

I've figured out why the custom deserializer doesn't work: the readValueAs method consumes the {, which triggers the exception, leaving } as the next token. This closes the inner object, and the parser will then think the enum value encountered next needs to be parsed as the inner type, not as the enum type.

我会明天试试这个,但我认为要走的是这个,在 deserialize 方法中:

I'll try this tomorrow, but I think the way to go is this, in the deserialize method:

ObjectMapper om = ...;

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

这篇关于杰克逊:忽略属性而不是抛出JsonMappingException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆