Java Jackson @JsonTypeName

1. Overview

Jackson is a versatile Java library that allows for efficient conversion between Java objects and their JSON representation. When dealing with inheritance and polymorphism in Java, there's a need to identify subtypes distinctly during the serialization and deserialization processes. Jackson’s @JsonTypeName annotation assists in this endeavor.

Annotation Overview

The @JsonTypeName annotation allows developers to specify a custom name for the subtype when dealing with polymorphism. Instead of using fully qualified class names, this annotation provides a way to use a more concise or meaningful name for the type in the serialized JSON.

2. Development Steps

1. Initialize a new Maven project.

2. Include the required Jackson dependencies.

3. Create an abstract User class, then define specific subtypes and apply the @JsonTypeName annotation.

4. Implement a separate class for serialization and deserialization logic.

5. Design a main class to demonstrate serialization and deserialization.

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

For our User Management System example:
// User.java
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeName;
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
public abstract class User {
    private String name;
    // Constructors, getters, setters...
}
@JsonTypeName("Administrator")
class Admin extends User {
    private String department;
    // Constructors, getters, setters...
}
@JsonTypeName("GuestUser")
class Guest extends User {
    private boolean temporaryAccess;
    // Constructors, getters, setters...
}
// UserSerializer.java
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class UserSerializer {
    public static String serialize(User user) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        return mapper.writeValueAsString(user);
    }
    public static User deserialize(String json) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        return mapper.readValue(json, User.class);
    }
}
// MainClass.java
public class MainClass {
    public static void main(String[] args) {
        User admin = new Admin();
        admin.setName("Alice");
        ((Admin) admin).setDepartment("IT");
        try {
            String json = UserSerializer.serialize(admin);
            System.out.println("Serialized JSON: " + json);
            User deserialized = UserSerializer.deserialize(json);
            System.out.println("Deserialized User Name: " + deserialized.getName());
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }
}

Output:

Serialized JSON: {"type":"Administrator","name":"Alice","department":"IT"}
Deserialized User Name: Alice

Code Explanation:

In this setup, the abstract class User represents the parent type with subtypes Admin and Guest

Using @JsonTypeName, we assign custom type names ("Administrator" for Admin and "GuestUser" for Guest). The @JsonTypeInfo annotation on User informs Jackson how to include type information in the serialized JSON. 

The UserSerializer class handles both serialization and deserialization, using Jackson's ObjectMapper

The MainClass demonstrates this by serializing an Admin instance and then deserializing it.

6. Conclusion

The @JsonTypeName annotation in Jackson provides an elegant way to specify custom type names when working with polymorphic types. By utilizing this, developers can maintain a cleaner and more understandable JSON output, enhancing clarity and interoperability in applications.

Comments