Jackson Json - @JsonTypeInfo, using Logical Type Name with @JsonSubTypes and @JsonTypeName

[Last Updated: Aug 11, 2020]

In the last two tutorials we used @JsonTypeInfo with use = JsonTypeInfo.Id.CLASS which causes fully-qualified Java class name to be serialized as the type identifier. Java class name may not be a good choice when the serialized JSON is consumed by non-Java clients. In that case we can use "logical type name" as use = JsonTypeInfo.Id.NAME. In that case name will then need to be separately resolved to actual concrete type (Class) via @JsonSubTypes and @JsonTypeName annotations.


It is used for binding logical name that the annotated class has. For example:

public class Rectangle extends Shape {


Defines subtypes along with an optional name. It is used with @JsonTypeInfo. For example:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY)
@JsonSubTypes( @JsonSubTypes.Type(value = Rectangle.class, name = "rectangle"))
public abstract class Shape {

If name is missing, class of the type will be checked for @JsonTypeName annotation, and if that is also missing or empty, a default name will be constructed. Default name is usually based on class name.


Java Objects

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY)
      @JsonSubTypes.Type(value = Rectangle.class),
      @JsonSubTypes.Type(value = Circle.class)})
public abstract class Shape {
public class Rectangle extends Shape {
  private int w;
  private int h;
public class Circle extends Shape {
  int radius;
public class View {
  private List<Shape> shapes;

Serializing and deserializing

public class ExampleMain {
  public static void main(String[] args) throws IOException {
      View v = new View();
      v.setShapes(new ArrayList<>(List.of(Rectangle.of(3, 6), Circle.of(5))));

      System.out.println("-- serializing --");
      ObjectMapper om = new ObjectMapper();
      String s = om.writeValueAsString(v);

      System.out.println("-- deserializing --");
      View view = om.readValue(s, View.class);
-- serializing --
-- deserializing --
View{shapes=[Rectangle{w=3, h=6}, Circle{radius=5}]}

Specifying 'property'

In above example the type 'name' is serialized with property "@type" which is the default when use=JsonTypeInfo.Id.NAME is used. To change that we can use property element. For example

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "typeName")

which will serialize to:


Using a type wrapper instead of JsonTypeInfo.As.PROPERTY

We can also specify use = JsonTypeInfo.Id.NAME with include = JsonTypeInfo.As.WRAPPER_OBJECT or include = JsonTypeInfo.As.WRAPPER_ARRAY (see last tutorial). In that case we don't need to specify property element. For example

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT)

which will serialize to:


Example Project

Dependencies and Technologies Used:

  • jackson-databind 2.9.6: General data-binding functionality for Jackson: works on core streaming API.
  • JDK 10
  • Maven 3.3.9

@JsonTypeInfo with @JsonSubTypes and @JsonTypeName Example Select All Download
  • jackson-json-type-info-with-json-type-name
    • src
      • main
        • java
          • com
            • logicbig
              • example

    See Also