【问题标题】:Jackson: ignoring properties instead of throwing JsonMappingException杰克逊:忽略属性而不是抛出 JsonMappingException
【发布时间】:2012-01-12 15:01:29
【问题描述】:

我有一个类需要使用 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" : {} } }

Jackson 在遇到这个时抛出这个异常:

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 我不在乎。如果无法反序列化,有什么方法可以告诉 Jackson 忽略此属性(并存储 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 的内部序列化值并反序列化它,它工作正常。

【问题讨论】:

  • 还有一个数据点:B 类还有一个枚举字段,它与A 中的B 引用同名:public EnumType b。当 Jackson 去反序列化内部类型 B 时,它似乎感到困惑并试图将其反序列化为 A

标签: java json jackson


【解决方案1】:

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

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

ObjectMapper om = ...;

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

【讨论】:

  • 看起来不错。如果arg0.readValueAs(JsonNode.class) 不起作用,您可以尝试使用arg0.readValueAsTree(),它也会返回一个JsonNode。
猜你喜欢
  • 1970-01-01
  • 2015-03-28
  • 1970-01-01
  • 2023-04-10
  • 1970-01-01
  • 2016-04-19
  • 2016-01-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多