【问题标题】:Jackson BeanSerializerModifier.modifySerializer & interfaces that modify how a JsonSerializer is handledJackson BeanSerializerModifier.modifySerializer & 修改 JsonSerializer 处理方式的接口
【发布时间】:2015-04-25 07:10:08
【问题描述】:

一些接口,如ResolvableSerializerContextualSerializer,会修改Jackson 处理JsonSerializer 的方式。

还有其他这样的接口吗?

Jackson 是否曾针对 JsonSerializer 的子类(例如 StdSerializerBeanSerializerBaseBeanSerializer)修改其行为? (当然,除了通过标准多态性;我说的是instanceofClass.isAssignableFrom() 等)

在我编写的BeanSerializerModifier 的子类中的modifySerializer 的实现中,我返回一个包装了参数JsonSerializerJsonSerializer 的子类。这个包装器只覆盖了两个方法:

  • serialize: 只有满足特定条件才会在封装的序列化器上调用序列化
  • getDelegatee:返回包装好的序列化器

问题:

  1. 我的包装器是否应该扩展JsonSerializer 的某个子类而不仅仅是JsonSerializer
    1. 如果是,子类是否应该依赖于封装的序列化器的类?
  2. 我的包装器是否应该重载任何其他方法?
  3. 我的包装器是否应该实现与包装的序列化器相同的序列化器修饰符接口?如果是这样,那么有两个问题:
    1. 我必须了解每个修饰符界面,并更新我的 BeanSerializerModifier 以处理添加到 Jackson 的任何新界面
    2. 我需要为每个修饰符接口的组合有一个不同的包装类,这很麻烦

【问题讨论】:

    标签: jackson


    【解决方案1】:

    好问题。以下是一些想法:

    • 通常您应该扩展 StdSerializer 而不是“原始”JsonSerializer
    • 如果序列化为 JSON 标量值,您可能需要扩展 StdScalarSerializer
    • 一般来说,基本类型不需要匹配,尽管如果委派给CollectionMap 序列化程序,您可能希望这样做——但是,通常,您应该需要匹配。一旦你正确地记下它就会变得不切实际。
    • 关于重载:有几种方法可以选择重载,通常只是委托给被委托人:
      • 对于多态处理,定义“serializeWithType(...)”
      • isEmpty(),如果存在与“空”概念相关的非空值:例如,字符串“”被认为是空的。
      • acceptJsonFormatVisitor() 是支持 JSON Schema 生成和其他类型自省所必需的(如生成 Avro、CSV 和 Protobuf 模式,使用匹配的数据格式模块)

    【讨论】:

    • 我仍然不清楚我应该如何处理 ResolvableSerializer 和 ContextualSerializer。我见过 Jackson 代码检查序列化程序是否是其中一个接口的实例。如果是这样,那么它会强制转换并调用接口方法。我还没有看到这样的代码检查受托人是否是实例。因此,如果我希望我的包装器尽可能透明,它必须实现受委托者实现的所有这些标记接口,对吗?如果只有 2 个标记接口,这意味着我必须有 4 个版本的包装类。每当添加另一个标记时,我都必须添加更多,对吧?
    • 既然我重写了 BeanSerializerModifier.modifySerializer,那么 JsonSerializer 参数是否总是一个 BeanSerializer?如果是这样,那么我的包装器可以扩展 BeanSerializer 而不是 StdSerializer 吗? BeanSerializer 已经实现了我所知道的两个标记接口,所以我只需要我的类的一个版本,而不是支持 StdSerializer 所有可能的标记接口组合所需的 4 个版本(一个用于实现无,仅可解析,仅上下文相关,以及两者)。
    • 最后,我要问一个关于 SO 的全新 Jackson 问题,因为我调查了所有这些东西以获得我在 Jackson 中找不到的更高级别的功能。但也许它存在,我错过了它。发布后,我将链接到该问题。再次感谢所有的帮助,也感谢杰克逊。
    • 关于我试图通过 BeanSerializerModifier 实现的更高级别功能的问题:stackoverflow.com/questions/29859551/…
    • 我尝试编写一个扩展BeanSerializerBaseForwardingBeanSerializer 类,用协变返回类型BeanSerializerBase 覆盖getDelegatee(),并委托JsonSerializerStdSerializer 中定义的所有方法& BeanSerializerBasegetDelegatee()。但是,这不起作用,因为许多方法都受到保护,所以虽然我的包装类可以覆盖这些方法,但它不能在受委托者上调用它们。是否可以公开所有这些方法,以便我的包装器可以在其受委托者上调用它们?还是我不应该委托受保护的方法?
    猜你喜欢
    • 1970-01-01
    • 2012-05-25
    • 2014-10-30
    • 1970-01-01
    • 1970-01-01
    • 2012-05-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多