【问题标题】:Set Type Discriminator programmatically in Jackson在 Jackson 中以编程方式设置类型鉴别器
【发布时间】:2020-11-10 20:15:06
【问题描述】:

对于多态反序列化,Jackson 的 ObjectMapper 想知道:

  1. 需要考虑哪些子类型
  2. 如何决定使用哪个子类型

有一些标准方法,使用完全限定的类名和某些保留的 JSON 属性,因此 Jackson 无需进一步配置即可扣除这些东西。

另一种常见的方法是,通过将注解@JsonTypeInfo@JsonSubtypes 添加到基本类型来为Jackson 提供必要的信息。然而,这意味着,无论何时添加新的子类型,都必须修改声明基类的文件。

还可以在运行时通过objectMapper.registerSubtypes(...) 以编程方式将子类型注册到ObjectMapper。

现在我正在寻找一种方法,在运行时以编程方式提供来自 @JsonTypeInfo 的信息,而不使用该注释。

类似于objectMapper.addTypeInfo(new TypeInfo(BaseType.class, PROPERTY, "myPropertyName", NAME); 的东西,所以我可以对另一个项目中声明的类型使用多态反序列化,它对 Jackson 或其任何注释一无所知。

【问题讨论】:

    标签: java jackson jackson-databind


    【解决方案1】:

    要在不修改实际类的情况下注册@JsonTypeInfo,您必须使用这样的mixin:

    // actual base type that we don't want to or can't modfiy 
    // because it is in a different module / 3rd party
    public class BaseType {  
        ...
    }
    
    // mixin for BaseType to define @JsonTypeInfo
    // this can be in a completely different package / module
    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
            include = JsonTypeInfo.As.PROPERTY, property = "type")
    public abstract class BaseTypeMixIn {
    }
    

    必须为 ObjectMapper 手动注册 mixin:

    objectMapper.addMixIn(BaseType.class, BaseTypeMixIn.class);
    

    BaseType 现在有效地拥有来自 mixin 的 @JsonTypeInfo。 jackson 中的 Mixin 是解决“如何注释一个我无法修改的类”问题的通用解决方案。

    对于子类型,可以使用ObjectMapper.registerSubtypes 注册类型信息,或者使用@JsonSubtypes 注释mixin。在这种情况下,我更喜欢在没有注释的情况下进行操作,因为如果不同的模块具有不同的基本类型的子类型,它也可以工作。注册多个 mixin 很可能不起作用。

    public class SubTypeA extends BaseType {
       ...
    }
    
    public class SubTypeB extends BaseType {
        ...
    }
    

    在 ObjectMapper 中注册:

    objectMapper.registerSubtypes(
       new NamedType(SubTypeA.class, "A"), 
       new NamedType(SubTypeB.class, "B"));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-25
      相关资源
      最近更新 更多