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

Jackson序列化:如何忽略超类属性

茅昀
2023-03-14
问题内容

我想序列化一个不受我控制的POJO类,但是想避免序列化任何来自超类而不是最终类的属性。例:

public class MyGeneratedRecord extends org.jooq.impl.UpdatableRecordImpl<...>,
    example.generated.tables.interfaces.IMyGenerated {
  public void setField1(...);
  public Integer getField1();

  public void setField2(...);
  public Integer getField2();
...
}

您可以从示例中猜测到,该类是由JOOQ生成的,并且是从复杂的基类UpdatableRecordImpl继承的,该基类还具有一些类似于bean属性的方法,这会在序列化过程中引起问题。另外,我有几个类似的类,因此最好避免对所有生成的POJO复制相同的解决方案。

到目前为止,我已经找到以下可能的解决方案:

  • 使用如下混合方法忽略超类的特定字段:如何告诉杰克逊忽略无法控制源代码的属性?

这样做的问题是,如果基类发生更改(例如,其中出现了新的getAnything()方法),则它可能会破坏我的实现。

  • 实现自定义序列化程序并在那里处理问题。对我来说,这似乎有些矫kill过正。

  • 顺便说一句,我有一个接口准确描述了我要序列化的属性,也许我可以混入@JsonSerialize(as = IMyGenerated.class)批注…?我可以将其用于我的目的吗?

但是,从纯粹的设计角度来看,最好的办法是能够告诉杰克逊,我只想序列化最后一个类的属性,而忽略所有继承的属性。有没有办法做到这一点?

提前致谢。


问题答案:

您可以注册一个自定义的Jackson注释Intropector,它将忽略来自某种超级类型的所有属性。这是一个例子:

public class JacksonIgnoreInherited {

    public static class Base {
        public final String field1;

        public Base(final String field1) {
            this.field1 = field1;
        }
    }

    public static class Bean extends Base {
        public final String field2;

        public Bean(final String field1, final String field2) {
            super(field1);
            this.field2 = field2;
        }
    }

    private static class IgnoreInheritedIntrospector extends JacksonAnnotationIntrospector {
        @Override
        public boolean hasIgnoreMarker(final AnnotatedMember m) {
            return m.getDeclaringClass() == Base.class || super.hasIgnoreMarker(m);
        }
    }

    public static void main(String[] args) throws JsonProcessingException {
        final ObjectMapper mapper = new ObjectMapper();
        mapper.setAnnotationIntrospector(new IgnoreInheritedIntrospector());
        final Bean bean = new Bean("a", "b");
        System.out.println(mapper
                        .writerWithDefaultPrettyPrinter()
                        .writeValueAsString(bean));
    }

}

输出:

{“ field2”:“ b”}



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

  • 问题内容: 我有一些扩展的模型类:它们定义用于包装Map的get和put方法的getter和setter。我正在尝试使用Jackson(带有RESTEasy)序列化这些类的实例,但是Jackson拒绝注意我的getter(使用注释)。而是仅序列化支持映射的键- 值对。我尝试使用禁用所有方法和字段的自动检测功能,但这并没有任何改变。有没有办法防止Jackson序列化Map,还是必须创建不扩展的新模型

  • 我有一个实体具有多个关联。我正在使用spring-boot公开一个REST API。目前,我有多个REST API,它们返回整个实体的JSON响应,包括关联。 但我不想序列化所有REST API中的所有关联对象。 例如: API-1应返回parent+associationA对象 API-2应返回parent+associationA+associationB对象 API-3应返回parent+a

  • 问题内容: 我使用以下代码来序列化从外部服务获得的响应,并作为我的服务的一部分返回json响应。但是,当外部服务返回带有时区(10:30:00.000-05.00)的时间值时,杰克逊会将其转换为15:30:00。如何忽略时区值? 问题答案: 您可以创建自定义解串器 告诉杰克逊使用您的自定义解串器 并像这样使用它: 您可以使用Jackson自定义序列化为服务响应添加时区信息

  • 我有一个这样的对象: 我是否可以使用和我的条件来仅在不为负数的情况下包含该值?或者有没有其他的解决办法我可以做到这一点?

  • 在这种情况下,如果验证失败,我希望将请求返回给用户,并附上相应的错误消息。我遇到的问题是,我使用Jackson处理JSON请求,验证失败也会导致Jackson无法序列化消息。 例如,如果我有此对象: ...当我去序列化时,字段无效(假设它有11个字符)... ...我得到了一个JsonProcessingException(错误验证对象)。我已经确认一个有效的对象序列化没有问题。所以我的问题是:我