当前位置: 首页 > 面试题库 >

Jackson:忽略属性,而不是抛出JsonMappingException

叶德运
2023-03-14
问题内容

我有一个需要使用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如果无法反序列化该属性,是否有任何方法告诉Jackson忽略该属性(并存储)?

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

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并对其进行反序列化,那么它将正常工作。


问题答案:

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

我明天会尝试,但是我认为方法是这样的deserialize:

ObjectMapper om = ...;

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


 类似资料:
  • 我有很多来自供应商的类,它们喜欢在属性访问上随机抛出RuntimeException。 我不能更改类,不能添加注释,而且为每个类定义混合是不现实的,因为堆栈的这部分经常更改。 如果属性的getter抛出异常,如何使Jackson忽略该属性?

  • 我有以下课程- 我如何通过使用Jackson JSON API动态地排除字段序列化?

  • 这是我的东西 当我得到响应时,我看到 我的看起来像 问题 如何消除中的值?

  • 问题内容: 我想序列化一个不受我控制的POJO类,但是想避免序列化任何来自超类而不是最终类的属性。例: 您可以从示例中猜测到,该类是由JOOQ生成的,并且是从复杂的基类UpdatableRecordImpl继承的,该基类还具有一些类似于bean属性的方法,这会在序列化过程中引起问题。另外,我有几个类似的类,因此最好避免对所有生成的POJO复制相同的解决方案。 到目前为止,我已经找到以下可能的解决方

  • 我使用JSON映射器从字符串中读取对象,然后从对象中写入字符串。我希望在写作时能够忽略一些属性。最简单的方法是什么?

  • > 使用mixin技术忽略来自超类的特定字段,如下所示:我如何告诉jackson忽略一个我无法控制源代码的属性? 这样做的问题是,如果基类发生了变化(例如,其中出现了一个新的getAnything()方法),它可能会破坏我的实现。 实现一个自定义序列化程序并在那里处理问题。这在我看来有点矫枉过正。 但是,从纯设计的角度来看,最好的方法是告诉jackson我只想序列化最终类的属性,而忽略所有继承的属