如何自定义Jackson类型的信息机制 [英] How to customize Jackson type information mechanism

查看:343
本文介绍了如何自定义Jackson类型的信息机制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



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



我是什么需要,


  1. 我想仅包含多态类型的类型信息。

  2. 我想改变类型信息的默认格式(到键值对)

是否可以通过扭曲全局配置来实现上述两点? / p>

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



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



示例帮助很好。

解决方案

你为此可以使用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;

公共类CustomTypeResolverBuilder extends DefaultTypeResolverBuilder
{
public CustomTypeResolverBuilder()
{
super(DefaultTyping.NON_FINAL);
}

@Override
public boolean useForType(JavaType t)
{
if(t.getRawClass()。getName()。startsWith( test.jackson)){
return true;
}

返回false;
}
}

现在,请考虑你有 test.jackson 包中的Foo.java 和<$ c中的 Bar.java $ c> org.myorg package,每个包含一个名为integer的 int 变量和一个 String 变量名为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);
酒吧=新酒吧(20,酒吧);

System.out.println(objectMapper.writeValueAsString(foo));
System.out.println(objectMapper.writeValueAsString(bar));

相应的输出将是:

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

您还可以自定义代表该类型的属性的名称( @CLASS在上面的例子中)。希望这有帮助!


In Jackson, I am using annotation @JsonTypeInfo to include polymorphism support.

If, I do not want to go with annotation based approach, I can use global default typing or override the type information handling module.

I have tried global type information but it is emitting type information for all non final type.

What I need ,

  1. I want to include type information only for polymorphic type.
  2. I want to change default format of type info (to key-value pair)

Is it possible to achieve above two points just by twitting global configuration?

If not, what extension point should I used used to customize type-information module ? I have read JacksonAnnotationIntrospector is the class which deals with type info.

Should I customize it to achieve above mentioned two points?

Help with Example will be well and good.

解决方案

You can use Jackson's DefaultTypeResolverBuilder for this purpose. Extend this class and override the useForType method appropriately. Here is an example that adds type information only for the classes belonging to the test.jackson package (and sub-packages):

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

Now, consider that you have Foo.java in test.jackson package and Bar.java in org.myorg package, each containing an int variable called "integer" and a String variable called "string".

You can serialize objects of these two classes this way:

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));

The corresponding output will be:

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

You can also customize the name of the attribute that represents the type ("@CLASS" in the above example). Hope this helps!

这篇关于如何自定义Jackson类型的信息机制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆