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 ,
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With