【问题标题】:How to customize Jackson type information mechanism如何自定义 Jackson 类型信息机制
【发布时间】:2012-09-10 14:28:13
【问题描述】:

在 Jackson 中,我使用注释 @JsonTypeInfo 来包含多态性支持。

如果我不想使用基于注释的方法,我可以使用全局默认类型或覆盖类型信息处理模块。

我尝试了全局类型信息,但它正在为所有非最终类型发出类型信息。

我需要什么,

  1. 我只想包含多态类型的类型信息。
  2. 我想更改类型信息的默认格式(键值对)

通过twitting全局配置是否可以实现以上两点?

如果不是,我应该使用什么扩展点来自定义类型信息模块? 我读过 JacksonAnnotationIntrospector 是处理类型信息的类。

我应该自定义它以实现上述两点吗?

对示例的帮助会很好。

【问题讨论】:

    标签: json jackson


    【解决方案1】:

    为此,您可以使用 Jackson 的 DefaultTypeResolverBuilder。扩展此类并适当地覆盖useForType 方法。这是一个仅为属于test.jackson 包(和子包)的类添加类型信息的示例:

    import com.fasterxml.jackson.databind.JavaType;
    import com.fasterxml.jackson.databind.ObjectMapper.DefaultTypeResolverBuilder;
    import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping;
    
    public class CustomTypeResolverBuilder extends DefaultTypeResolverBuilder
    {
        public CustomTypeResolverBuilder()
        {
            super(DefaultTyping.NON_FINAL);
        }
    
        @Override
        public boolean useForType(JavaType t)
        {
            if (t.getRawClass().getName().startsWith("test.jackson")) {
                return true;
            }
    
            return false;
        }
    }
    

    现在,假设您在test.jackson 包中拥有Foo.java,在org.myorg 包中拥有Bar.java,每个都包含一个名为“整数”的int 变量和一个名为“字符串”的String 变量。

    你可以这样序列化这两个类的对象:

    ObjectMapper objectMapper = new ObjectMapper();
    
    TypeResolverBuilder<?> typeResolver = new CustomTypeResolverBuilder();
    typeResolver.init(JsonTypeInfo.Id.CLASS, null);
    typeResolver.inclusion(JsonTypeInfo.As.PROPERTY);
    typeResolver.typeProperty("@CLASS");
    objectMapper.setDefaultTyping(typeResolver);
    
    Foo foo = new Foo(10, "Foo");
    Bar bar = new Bar(20, "Bar");
    
    System.out.println(objectMapper.writeValueAsString(foo));
    System.out.println(objectMapper.writeValueAsString(bar));
    

    相应的输出将是:

    {"@CLASS":"test.jackson.Foo","integer":10,"string":"Foo"}
    {"integer":20,"string":"Bar"}
    

    您还可以自定义表示类型的属性名称(上例中的“@CLASS”)。希望这会有所帮助!

    【解决方案2】:

    您可以使用Moonwlker 库。

    有了它,你可以像这样创建ObjectMapper

     ObjectMapper objectMapper = new ObjectMapper();
    
     MoonwlkerModule module =
       MoonwlkerModule.builder()
         .fromProperty("@CLASS").toSubclassesOf(Animal.class)
         .build();
    
     objectMapper.registerModule(module);
    

    然后使用该映射器进行(反)序列化。 Moonwlker 网站包含更多详细信息和配置选项。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-01
      • 2016-07-17
      • 1970-01-01
      相关资源
      最近更新 更多