<link rel="stylesheet" href="styles-3GBANQL6.css">
← Back to blog

Spring Boot

Understanding Jackson Annotations

Understanding Jackson Annotations

Jackson is a popular library in Java used for converting Java objects to JSON and vice versa. Its powerful annotation system allows developers to customize the serialization and deserialization processes according to their needs. In this article, we will explore various Jackson annotations extensively, providing detailed explanations and code examples for each.

1. Jackson Serialization Annotations

Serialization is the process of converting a Java object into a JSON representation. Here are the key serialization annotations:

@JsonProperty

The @JsonProperty annotation is used to specify the property name in the JSON output. You can also use it to mark a property as required.

import com.fasterxml.jackson.annotation.JsonProperty;

    public class User {
        @JsonProperty("user_name")
        private String name;

        @JsonProperty(required = true)
        private String email;

        // Getters and Setters
    }

@JsonIgnore

The @JsonIgnore annotation is used to exclude a field from serialization. This is useful when you want to hide sensitive information or prevent circular references.

import com.fasterxml.jackson.annotation.JsonIgnore;

    public class User {
        private String name;

        @JsonIgnore
        private String password; // Will not be included in JSON output

        // Getters and Setters
    }

@JsonInclude

The @JsonInclude annotation specifies which properties are included in the serialization based on certain criteria. It can be used to avoid null values or empty collections in the output.

import com.fasterxml.jackson.annotation.JsonInclude;
    import com.fasterxml.jackson.annotation.JsonInclude.Include;

    public class User {
        private String name;

        @JsonInclude(Include.NON_NULL) // Only include if not null
        private String email;

        @JsonInclude(Include.NON_EMPTY) // Only include if not empty
        private List roles;

        // Getters and Setters
    }

@JsonFormat

The @JsonFormat annotation is used to specify the format of date and time properties during serialization.

import com.fasterxml.jackson.annotation.JsonFormat;

    public class Event {
        private String title;

        @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
        private Date eventDate;

        // Getters and Setters
    }

@JsonAutoDetect

The @JsonAutoDetect annotation allows you to control the visibility of properties during serialization and deserialization. It lets you specify which fields are accessible based on their visibility (public, protected, etc.).

import com.fasterxml.jackson.annotation.JsonAutoDetect;
    import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;

    @JsonAutoDetect(fieldVisibility = Visibility.ANY) // Serialize all fields regardless of visibility
    public class User {
        private String name; // Private field will still be included

        // Getters and Setters
    }

2. Jackson Deserialization Annotations

Deserialization is the process of converting JSON back into Java objects. Here are the important deserialization annotations:

@JsonCreator

The @JsonCreator annotation is used to indicate a constructor or factory method that Jackson should use to create an instance of the class during deserialization.

import com.fasterxml.jackson.annotation.JsonCreator;
    import com.fasterxml.jackson.annotation.JsonProperty;

    public class User {
        private String name;
        private String email;

        @JsonCreator
        public User(@JsonProperty("user_name") String name, @JsonProperty("email") String email) {
            this.name = name;
            this.email = email;
        }

        // Getters and Setters
    }

@JsonSetter

The @JsonSetter annotation allows you to specify a method to use for setting a property during deserialization.

import com.fasterxml.jackson.annotation.JsonSetter;

    public class User {
        private String name;

        @JsonSetter("user_name")
        public void setName(String name) {
            this.name = name;
        }

        // Getters
    }

3. Jackson Property Inclusion Annotations

These annotations control the inclusion of properties during serialization:

@JsonInclude

We already discussed this in the serialization section, but it applies to both serialization and deserialization. It helps prevent sending unnecessary data.

@JsonPropertyOrder

The @JsonPropertyOrder annotation allows you to specify the order in which properties are serialized.

import com.fasterxml.jackson.annotation.JsonPropertyOrder;

    @JsonPropertyOrder({ "email", "user_name" })
    public class User {
        private String name;
        private String email;

        // Getters and Setters
    }

4. Jackson Polymorphic Type Handling Annotations

These annotations help in handling polymorphic types during serialization and deserialization:

@JsonTypeInfo

The @JsonTypeInfo annotation is used to include type information in JSON for polymorphic types.

import com.fasterxml.jackson.annotation.JsonSubTypes;
    import com.fasterxml.jackson.annotation.JsonTypeInfo;

    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
    @JsonSubTypes({
        @JsonSubTypes.Type(value = Dog.class, name = "dog"),
        @JsonSubTypes.Type(value = Cat.class, name = "cat")
    })
    public abstract class Animal {
        // Abstract class for animals
    }

@JsonSubTypes

This annotation is used alongside @JsonTypeInfo to define the subclasses for polymorphic type handling.

5. Jackson General Annotations

These are general-purpose annotations that apply to various scenarios:

@JsonRootName

The @JsonRootName annotation is used to define the name of the root element in the serialized JSON.

import com.fasterxml.jackson.annotation.JsonRootName;

    @JsonRootName(value = "user")
    public class User {
        private String name;

        // Getters and Setters
    }

@JsonAnyGetter and @JsonAnySetter

These annotations allow you to handle dynamic properties in your object.

import com.fasterxml.jackson.annotation.JsonAnyGetter;
    import com.fasterxml.jackson.annotation.JsonAnySetter;

    public class User {
        private String name;
        private Map additionalProperties = new HashMap<>();

        @JsonAnyGetter
        public Map getAdditionalProperties() {
            return additionalProperties;
        }

        @JsonAnySetter
        public void setAdditionalProperty(String name, Object value) {
            this.additionalProperties.put(name, value);
        }
    }

6. @JsonManagedReference and @JsonBackReference

These annotations are used to handle bidirectional relationships in serialization:

@JsonManagedReference

This annotation indicates the "forward" part of a reference.

import com.fasterxml.jackson.annotation.JsonManagedReference;

    public class User {
        private String name;

        @JsonManagedReference
        private List posts;

        // Getters and Setters
    }

@JsonBackReference

This annotation indicates the "back" part of a reference.

import com.fasterxml.jackson.annotation.JsonBackReference;

    public class Post {
        private String title;

        @JsonBackReference
        private User user;

        // Getters and Setters
    }

7. Custom Jackson Annotations

You can create custom annotations by extending existing Jackson annotations. Here’s an example:

import com.fasterxml.jackson.annotation.JsonProperty;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;

    @Retention(RetentionPolicy.RUNTIME)
    @JsonProperty
    public @interface CustomJsonProperty {
        String value();
    }

8. Jackson MixIn Annotations

MixIn annotations allow you to add annotations to existing classes without modifying them.

import com.fasterxml.jackson.annotation.JsonProperty;

    public abstract class UserMixIn {
        @JsonProperty("user_name")
        String name;
    }

9. Disable Jackson Annotations

You can disable specific features of Jackson using annotations. For instance, you can prevent Jackson from failing on empty beans:

import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.SerializationFeature;

    ObjectMapper mapper = new ObjectMapper();
    mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); // Disable failing on empty beans
    

Conclusion

Jackson provides a robust set of annotations that enable developers to customize how Java objects are serialized and deserialized to and from JSON. Understanding these annotations and their appropriate use cases is crucial for developing effective Java applications that interact with JSON data.

By leveraging the power of Jackson annotations, you can ensure that your application's data handling meets the necessary requirements for structure, security, and performance.

LET'S BUILD WHAT'S NEXT

Ready to turn your idea into a real solution?

Let's discuss how we can help you create value with technology.

Let's Talk