Java Jackson @JsonTypeInfo

1. Overview

Jackson is a powerful Java library renowned for its ability to convert Java objects into JSON and vice versa. When dealing with polymorphic types, there is a need to include type information in the serialized JSON to ensure proper deserialization. The @JsonTypeInfo annotation provided by Jackson helps address this challenge.

@JsonTypeInfo Annotation Overview

The @JsonTypeInfo annotation is utilized to specify how polymorphic type information should be included in the serialized JSON. This helps Jackson determine the correct subtype to instantiate during deserialization.

2. Development Steps

1. Set up a new Maven project.

2. Incorporate the essential Jackson dependencies.

3. Create a User superclass and specific subtypes, and apply the @JsonTypeInfo annotation to capture type information.

4. Construct a separate class for serialization logic.

5. Devise a main class to demonstrate the serialization.

3. Create a Maven Project

There are different ways to create a simple Maven project:

Create a Simple Maven Project using the Command Line Interface

Create a Simple Maven Project using  Eclipse IDE

Create a Simple Maven Project using  IntelliJ IDEA

4. Maven Dependencies

Open the pom.xml file, and add the following Jackson data binding dependency:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.0</version>
</dependency>

5. Code Program

Using the User Management System as a template, let's dive in:
// User.java
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeName;
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
        @JsonSubTypes.Type(value = Admin.class, name = "admin"),
        @JsonSubTypes.Type(value = Guest.class, name = "guest")
})
public abstract class User {
    private String username;
    // Constructors, getters, setters...
}

@JsonTypeName("admin")
class Admin extends User {
    private String adminId;
    // Constructors, getters, setters...
}

@JsonTypeName("guest")
class Guest extends User {
    private String guestToken;
    // Constructors, getters, setters...
}

// JsonSerializer.java
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonSerializer {
    public static String serializeToJson(Object object) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        return mapper.writeValueAsString(object);
    }
}

// MainClass.java
public class MainClass {
    public static void main(String[] args) {
        User admin = new Admin();
        admin.setUsername("alice");
        ((Admin) admin).setAdminId("A123");
        try {
            String json = JsonSerializer.serializeToJson(admin);
            System.out.println(json);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }
}

Output:

{"type":"admin","username":"alice","adminId":"A123"}

Code Explanation:

The User class is an abstract superclass with subclasses Admin and Guest

The @JsonTypeInfo annotation on the User class indicates that a "type" property will determine which subtype to instantiate during deserialization. 

The @JsonSubTypes annotation enumerates possible subtypes. The JsonSerializer class contains logic to serialize a Java object to its JSON representation. 

The MainClass sets up a sample user of type Admin and showcases its serialization, which includes the type information.

6. Conclusion

The @JsonTypeInfo annotation in Jackson provides a streamlined approach to handle polymorphism during JSON serialization and deserialization. With this feature, developers can maintain robust type safety even when working with complex hierarchies in a JSON context.

Comments