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

我想序列化一个不受我控制的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生成的,并且inheritance自复杂的基类UpdatableRecordImpl,它还具有一些类似于bean属性的方法,这会在序列化期间导致问题。 此外,我有几个类似的类,因此最好避免为我生成的所有POJO重复相同的解决方案。

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

  • 使用mixin技术忽略来自超类的特定字段,如下所示: 如何告诉jackson忽略我无法控制源代码的属性?

    这个问题是如果基类发生变化(例如,新的getAnything()方法出现在它中),它可能会破坏我的实现。

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

  • 顺便说一下,我有一个接口,它描述了我想要序列化的属性,也许我可以混合一个@JsonSerialize(as = IMyGenerated.class)注释……? 我可以将此用于我的目的吗?

但是,从纯粹的设计角度来看,最好的方法是能够告诉jackson我只想序列化最终类的属性,并忽略所有inheritance的属性。 有没有办法做到这一点?

提前致谢。

您可以注册一个自定义的Jackson注释内部操作程序 ,它将忽略来自某个超类型的所有属性。 这是一个例子:

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

您可以覆盖要阻止输出的超类’方法,并使用@JsonIgnore注释它们。 覆盖将属性创建的控制转移到子类,同时使其能够从输出中过滤它。

例如:

 public class SomeClass { public void setField1(...); public Integer getField1(); public void setField2(...); public Integer getField2(); @Override @JsonIgnore public String superClassField1(...){ return super.superClassField1(); }; @Override @JsonIgnore public String superClassField2(...){ return super.superClassField2(); }; ... } 

inheritance的良好用法是子类扩展或添加function。 所以通常的方法是序列化数据。

workarround将使用值对象(VO)或数据传输对象(DTO)以及您需要序列化的字段。 脚步:

  • 使用应序列化的字段创建VO类。
  • 使用BeanUtils.copyProperties(目标VO,源数据)来复制属性
  • 序列化VO实例。