Prior to Jackson 1.2, the only way to serialize or deserialize JSON using Jackson was by using one of the following two methods:

  • Adding annotations to modify the POJO classes
  • Writing custom serializers and deserializers

Now imagine you want to serialize or deserialize a 3rd party POJO which you don’t have access to its source code. What would you do?

Also, you might want your code clean and open to other JSON library, such as GSON.

What would you do to decouple your code from Jackson annotations?

Jackson mix-in annotations helps you resolve this kind of problems. These annotations are used in a mix-in class or interface but function as if they were directly included in the target class.

In this post we will look at how to use the Jackson mix-in annotations.

Sample Application

Let us create a simple Spring Boot application to understand how Jackson mix-in annotation works.

Consider you want serialize or deserialize a User POJO in a Spring Boot application.

Here is code of the User POJO.

User.java

In the preceding code, User is a typical POJO but is not designed to be used with data binding. The User class doesn’t have the default constructor and neither any getter and setter methods.

Let’s assume that you don’t have access to the source code of the User POJO. Or there is some constraint disallowing you to modify the existing POJO. In this scenario, you can’t serialize or deserialize a User object through annotations or by defining your own custom serializer and deserializer.

Let us see how mix-in annotations can solve this problem.

The Jackson Mix-in Class

For mix-in annotation, you first need to define a mix-in class or interface.

Let’s define an abstract mix-in class for User. Ensure that the mix-in class have a constructor matching the source POJO.

Use the @JsonCreator annotation on the constructor and the @JsonProperty property to specify all the properties of the POJO.

Here is code for the UserMixin Jackson mix-in class.

UserMixin.java

UserMixin is an abstract class where the constructor of the class is annotated with @JsonCreator to tell Jackson in what order to pass fields from a JSON object to the constructor.

Each argument of the constructor is annotated with @JsonProperty to indicate the name of the property to bind to.

After creating the UserMixin class, you must configure the ObjectMapper to use the mix-in for the User POJO, like this.

Here is the complete test code to test the Jackson mix-in.

UserTest.java

As you can see in the code, ObjectMapper is configured in the buildMapper() method.

In the test method, an ObjectMapper is created and the addMixIn() method is called on it. The addMixIn() method configures the association between the mix-in and target classes, to be used during serialization.

Here is the output of the Jackson Mix-in test from IntelliJ:

Jackson Mixin Test Results

2
Share

JSON has become the most preferred way of transmitting data across network connections. JSON being easily readable by machines is one of the many reasons for JSON’s popularity. However, JSON unless formatted well, is not easily readable by human. Pretty printing a JSON is one common operation to improve the readability of the JSON. Enabling pretty print for Jackson is easy when you are using Jackson on its own. Even easier when you are using Jackson with Spring Boot.

In this post, I will explain how to pretty print JSON using the Jackson library standalone, and the Spring configuration under Spring Boot.

The Maven POM

In order to use Jackson, you need the Jackson JAR files. If you are using Maven, include the Jackson dependencies in your Maven POM.

Here is the code to add the Jackson dependencies.

Note: When using Spring Boot, the Jackson dependencies are typically included under the Spring Boot starters.

The POJO

Let’s create a JsonPrettyPrintDemoBean POJO with few fields that will be serialized to JSON.

The JsonPrettyPrintDemoBean POJO is this.

JsonPrettyPrintDemoBean.java

Pretty Print JSON Object

Let us serialize the JsonPrettyPrintDemoBean POJO into JSON. A test class to test the serialization and print the serialized object is this.

The output of running the test is this.

As you can notice in the preceding output, the JSON is compact. It is not formatted and therefore difficult to read. Imagine such output for a large number of properties. Lack of proper formatting makes it difficult to read or search the JSON for any particular key or value. To address this challenge, you can pretty print JSON.

To enable pretty printing, you need to call the writerWithDefaultPrettyPrinter() on the ObjectMapper(), like this.

With pretty printing, the output JSON is this.

Pretty Print JSON String

Let’s try to use writerWithDefaultPrettyPrinter() with a JSON string with this code snippet.

The output printed is in compact mode and will be the same as the String input.

To enable pretty printing, read the JSON string into an object. In our example, we can read the jsonString into the JsonPrettyPrintDemoBean POJO. Then, enable pretty printing, with a call the writerWithDefaultPrettyPrinter() on the ObjectMapper, like this.

The output is this.

If you only need to pretty print a JSON string, you can use Object instead of creating an application POJO.

The code to do so is this.

The output with pretty print is this.

The complete test code is this.

JsonPrettyPrintDemoBeanTest.java

The output of running the test in IntelliJ is this.

Output of running the test class in IntelliJ

Pretty Printing Jackson with Spring Boot

A common use case for pretty printing JSON is in Spring RESTFul Web services. Such services expose endpoints that clients consume. Clients can be front-end applications using some HTTP library, a browser sending GET requests, or a REST client such as Postman.

These clients make REST calls to the service and receives JSON data. At times, the clients might require presenting the data to users. Without pretty printing, the JSON returned by a Spring Boot REST service in Postman looks like this.
Raw JSON from Jackson under Spring Boot in Postman

For a human-readable format, we need to enable JSON pretty printing.

With minimal changes you can enable pretty printing in your Spring Boot application.

The most convenient method is to enable pretty printing in the application.properties file, like this:

The second approach is to programmatically set the prettyPrint
field of MappingJackson2HttpMessageConverter to true. To do so, create a configuration class in your application like this.

JacksonPrettyPrintConfiguration.java

This configuration class extends WebMvcConfigurationSupport and overrides the extendMessageConverters() method. In this method, the setPrettyPrint() method is called on the MappingJackson2HttpMessageConverter object, passing true as the parameter.

With pretty printing enabled, the JSON output in Postman is this.
pretty print JSON from Jackson with Spring Boot

You can download the example code from here.

0
Share

Jackson is a suite of data-processing tools for Java comprising of three components:

  • Streaming (jackson-core) defines low-level streaming API, and includes JSON-specific implementations.
  • Annotations (jackson-annotations) contains standard Jackson annotations
  • Databind (jackson-databind) implements data-binding (and object serialization) support on streaming package. This package depends both on streaming and annotations packages

In this post, I will explain the Java objects to JSON data-binding using Jackson annotations. I will take up each of the Jackson annotations and explain with code snippets how to use them. Each annotation usage is accompanied with proper test cases.

Jackson Serialization and Deserialization Annotations

The Jackson library provides annotations that you can use in POJO’s to control both serialization and deserialization between POJOs and JSON. These annotations that are used in both serialization and deserialization operations are:

  • @JsonIgnore
  • @JsonIgnoreProperties
  • @JsonIgnoreType
  • @JsonAutoDetect

@JsonIgnore

The @JsonIgnore annotation marks a field of a POJO to be ignored by Jackson during serialization and deserialization. Jackson ignores the field both JSON serialization and deserialization. An example of Java class that uses the @JsonIgnore annotation is this.

IgnoreDemoBean.java

The test class to test the @JsonIgnore annotation is this.

IgnoreDemoBeanTest.java

The output on running the test in IntelliJ is this.
@JsonIgnore Annotation Test Output

As you can see, the @JsonIgnore annotation ignored the field personId both during serialization and deserialization.

@JsonIgnoreProperties

The @JsonIgnoreProperties annotation is used at the class level to ignore fields during serialization and deserialization. The properties that are declared in this annotation will not be mapped to the JSON content.

Let us consider an example of Java class that uses the @JsonIgnoreProperties annotation.

IgnorePropertiesDemoBean.java

The test code to test the @JsonIgnoreProperties annotation is this.

IgnorePropertiesDemoBeanTest

The output of running the test in IntelliJ is this.


As you can see, the @JsonIgnoreProperties annotation ignored the field userId and gender both during serialization and deserialization.

@JsonIgnoreType

The @JsonIgnoreType annotation is used to mark a class to be ignored during serialization and deserialization. It marks all the properties of the class to be ignored while generating JSON and reading JSON. An example of Java class that uses the @JsonIgnoreType annotation is this.

IgnoreTypeDemoBean.java

The test code to test the @JsonIgnoreProperties annotation is this.

IgnoreTypeDemoBeanTest.java

The output of running the test in IntelliJ is this.

@JsonAutoDetect

The @JsonAutoDetect annotation is used at the class level to tell Jackson to override the visibility of the properties of a class during serialization and deserialization. You can set the visibility with the following elements:

  • creatorVisibility
  • fieldVisibility
  • getterVisibility
  • setterVisibility
  • isGetterVisibility

The JsonAutoDetect class defines public static constants that are similar to Java class visibility levels. They are:

  • ANY
  • DEFAULT
  • NON_PRIVATE
  • NONE
  • PROTECTED_AND_PRIVATE
  • PUBLIC_ONLY

Let us consider an example of Java class that uses the @JsonAutoDetect annotation.

AutoDetectDemoBean.java

The test code to test the @JsonAutoDetect annotation is this.

The output of running the test in IntelliJ is this.

Jackson Serialization Annotations

Jackson provides several annotations that you can use in POJO’s to serialize Java objects to JSON. These annotations are:

  • @JsonValue
  • @JsonInclude
  • @JsonGetter
  • @JsonAnyGetter
  • @JsonPropertyOrder
  • @JsonRawValue
  • @JsonSerialize
  • @JsonRootName

@JsonValue

The @JsonValue annotation is used at the method level. This annotation tells Jackson to use this method to generate the JSON string from the Java object.

Typically, if you want to print a serialized object, you override the toString() method. But, by using the @JsonValue annotation, you can define the way in which the Java object is to be serialized.

Note: Jackson omits any quotation marks inside the String returned by the custom serializer.
Let us consider an example Java class that uses the @JsonValue annotation.

ValueDemoBean.java

In order to explain the difference between the serialized object with and without the @JsonValue annotation, the code includes the toString() method. You can also run the code without overriding the toString() method.

The test code to test the @JsonValue annotation is this.

ValueDemoBeanTest

The output of running the test in IntelliJ is this.

As shown in the preceding figure, the Java object is serialized by Jackson by calling the defined method toJson(). The quotation marks are added by Jackson.

@JsonInclude

The @JsonInclude annotation is used to exclude properties or fields of a class under certain conditions. This is defined using the JsonInclude.Include enum. This enum contains constants, that determine whether or not to exclude the property. The constants are:

  • ALWAYS
  • NON_DEFAULT
  • NON_EMPTY
  • NON_NULL

Let us consider an example Java class that uses the @JsonInclude annotation.

IncludeDemoBean.java

The test code to test the @JsonInclude annotation is this.

The output of running the test in IntelliJ is this.
@JsonInclude Test Output

As shown in the preceding figure, the JSON string does not contain the property nameas it is initialized to null.

@JsonGetter

The @JsonGetter annotation is used to customize the generated JSON keys. This is accomplished with the value argument of @JsonGetter. The value passed is the name that should be used as the JSON key.

Let us consider an example Java class that uses the @JsonGetter annotation.

GetterDemoBean.java

The test code to test the @JsonGetter annotation is this.

The output of running the test in IntelliJ is this.

As you can see in the example, the Java object is serialized with the property names that you defined using the @JsonGetter annotation. Without the annotations, the serialized JSON would contain the property names:  personId and personName.

@JsonAnyGetter

The @JsonAnyGetter annotation can be used when you don’t want to declare a property or a method for every possible key in JSON. This annotation is used on the getter methods which enables you to use a Map to hold all your properties that you want to serialize.

Let us consider an example Java class that uses the @JsonAnyGetter annotation.

AnyGetterDemoBean.java

The test code to test the @JsonAnyGetter annotation is this.

The output of running the test in IntelliJ is this.

@JsonAnyGetter Test Output
As you can see, all the properties are serialized as the properties of AnyGetterDemoBean object.

@JsonPropertyOrder

The @JsonPropertyOrder annotation tells Jackson to serialize the Java object to JSON, in the order specified as the arguments of the annotation. This annotation also allows partial ordering. The properties are first serialized in the order in which they are found, followed by any other properties not included in the annotation.

Let us consider an example of Java class that uses the @JsonPropertyOrder annotation.

PropertyOrderDemoBean.java

The test code to test the @JsonPropertyOrder annotation is this.

The output of running the test in IntelliJ is this.
@JsonPropertyOrder Test Output

As you can see the result, the name property is first serialized before the personId. Without the @JsonPropertyOrder annotation, the object would have been serialized in the order found in the class.

@JsonRawValue

The @JsonRawValue annotation is used on methods and fields. It tells Jackson to serialize the field or property as declared. For example, if you have a String field in your Java class, the JSON value that Jackson generates is enclosed within quotes (” “). But when you annotate the field with @JsonRawValue, Jackson omits the quotes.

Let us consider an example Java class that explains the use of @JsonRawValue.

RawValueDemoBean.java

Here, the address field is a JSON string. This JSON string will be serialized as a part of the final JSON string of the RawValueDemoBean object.

The test code to test the @JsonRawValue annotation is this.

The output of running the test in IntelliJ is this.

As you can see, the final JSON string of the Java object is generated as defined in the POJO class omitting the quotes.

@JsonSerialize

The @JsonSerialize annotation is used tell Jackson to use the declared custom serializer during the serialization of the field, which is marked with this annotation. Let us consider a POJO that uses the @JsonSerialize annotation.

SerializeDemoBean.java

Next, let us define a custom serializer that will serialize the activeDate field with a specific format.

CustomDateSerializer.java

The code to test the @JsonSerialize annotation is this.

The output of running the test in IntelliJ is this.

@JsonRootName

The @JsonRootName annotation can be used to tell Jackson to wrap the object to be serialized with a top-level element. You can pass the name as a parameter to the @JsonRootName annotation. Let us consider that you want to wrap your serialized Java object with the key user.

Here is an example of Java class that uses the @JsonRootName annotation.

RootNameDemoBean.java

The test code to test the @JsonRootName annotation is this.

The output of running the test in IntelliJ is this.
@JsonRootName Test Output

As you can see, the fields personId and name are wrapped within the user, where the latter is the key, and the former is the value of the property of the generated JSON.

Deserialization Annotations

Let us explore the JSON annotations that can be used to control deserialization of JSON into POJOs. The Jackson deserialization annotations are:

  • @JsonSetter
  • @JsonAnySetter
  • @JsonCreator
  • @JacksonInject
  • @JsonDeserialize

@JsonSetter

The @JsonSetter annotation tells Jackson to deserialize the JSON into Java object using the name given in the setter method. Use this annotation when your JSON property names are different to the fields of the Java object class, and you want to map them.

A Java class that uses the @JsonSetter annotation is this.

SetterDemoBean.java

The @JsonSetter annotation takes the name of the JSON key that must be mapped to the setter method.

The test code to test the @JsonSetter annotation is this.

The output of running the test in IntelliJ is this.

@JsonSetter Test Output

As you can see, the JSON to be serialized has a property id. But no field in the POJO matches this property. Now how will Jackson read this JSON? Here is where the @JsonSetter annotation can be used to map the property id to the field personId. This annotation instructs Jackson to use a setter method for a given JSON property.

@JsonAnySetter

The @JsonAnySetter annotation is used on setter methods of a Map field. Sometimes you may find some JSON values that cannot be mapped to the fields in the Java object class. In such a case, the @JsonAnySetter captures the data and stores them in a Map.

A Java class that uses the @JsonAnySetter annotation is this.

AnySetterDemoBean.java

The test code to test the @JsonAnySetter annotation is this.

The output of running the test in IntelliJ is this.
@JsonAnySetter Test Output

@JsonCreator

The @JsonCreator annotation tells Jackson that the JSON properties can be mapped to the fields of a constructor of the POJO. This is helpful when the JSON properties do not match with the names of the Java object field names. The @JsonCreator annotation can be used where @JsonSetter cannot be used. For example, immutable objects which need their initial values to be injected through constructors.

An example of Java class that uses the @JsonCreator annotation is this.

CreatorDemoBean.java

The test code to test the @JsonCreator annotation is this.

The output of running the test in IntelliJ is this.

@JacksonInject

The @JacksonInject annotation is used to tell Jackson that particular values of the deserialized object will be injected and not read from the JSON string.

An example of Java class where the personId field is injected by Jackson is this.

JacksonInjectDemoBean.java

In order to inject values into a field, you can use the InjectableValues class. You need to configure ObjectMapper to read both, the injected values from injectableValues and the remaining values from the JSON string.

The test code to test the @JacksonInject annotation is this.

The output of running the test in IntelliJ is this.
@JacksonInject Test Output

As you can see, the value for the field personId has been injected by Jackson and the other values are taken from the input JSON string.

@JsonDeserialize

The @JsonDeserialize annotation tells Jackson to use a custom deserializer while deserializing the JSON to Java object. To do so, you need to annotate the field to which you need to apply the custom deserializer.

A Java class that uses the @JsonDeserialize annotation is this.

DeserializeDemoBean.java

The custom deserializer that is referenced by the preceding DeserializeDemoBeanbean class is this.

CustomDateDeserializer.java

Here, the CustomDateDeserializer class extends the StdDeserializer class with a generic type Date. The overriden deserialize() method returns the Date object.

The test code to test the @JsonDeserialize annotation is this.

The output of running the test in IntelliJ is this.
@JsonDeserialize Test Output

General Annotations

The general annotations are:

  • @JsonProperty
  • @JsonFormat
  • @JsonUnwrapped
  • @JsonView
  • @JsonManagedReference and @JsonBackReference
  • @JsonIdentityInfo
  • @JsonFilter

@JsonProperty

The @JsonProperty annotation is used to map property names with JSON keys during serialization and deserialization. By default, if you try to serialize a POJO, the generated JSON will have keys mapped to the fields of the POJO. If you want to override this behavior, you can use the @JsonProperty annotation on the fields. It takes a String attribute that specifies the name that should be mapped to the field during serialization.

You can also use this annotation during deserialization when the property names of the JSON and the field names of the Java object do not match.

Let us consider an example Java class that uses the @JsonProperty annotation.

PropertyDemoBean.java

The test code to test the @JsonProperty annotation is this.

The output of running the test in IntelliJ is this.
@JsonProperty Test Output

@JsonFormat

The @JsonFormat annotation is used to tell Jackson that the format in which the value for a field is serialized. It specifies the format using the JsonFormat.Shape enum.

Let us consider an example Java class that uses the @JsonFormat annotation to modify the Date and Time format of an activeDate field.

FormatDemoBean.java

The test code to test the @JsonFormat annotation is this.

The output of running the test in IntelliJ is this.
@JsonFormat Test Output

@JsonUnwrapped

The @JsonUnwrapped annotation unwraps the values during serialization and deserialization. It helps in rendering the values of a composed class as if they belonged to the parent class. Let us consider an example of Java class that uses the @JsonUnwrapped annotation.

UnwrappedDemoBean.java

In this example, the Address class is inside the UnwrappedDemoBean class. Without the @JsonUnwrapped annotation, the serialized Java object would be similar to this.

Let us see what happens when you use the @JsonUnwrapped annotation.

The test code to test the @JsonUnwrapped annotation is this.

The output of running the test in IntelliJ is this.
@JsonUnwrapped Test Output

As you can see, the Address object is unwrapped and is displayed as the properties of the parent class UnwrappedDemoBean.

@JsonView

The @JsonView annotation is used to include or exclude a property dynamically during serialization and deserialization. It tells the view in which the properties are rendered. Let us consider an example Java class that uses the @JsonView annotation with Public and Internal views.

ViewDemoBean.java

The test code to test the @JsonView annotation is this.

As you can see in the test code, you need to configure the ObjectMapper to include which type of view must be used for writing the JSON from the Java object using the writerWithView() method.

The output of running the test in IntelliJ is this.

When the JSON is generated in the public view, only personId and name fields are serialized omitting the gender field. But when the JSON is generated in the internal view all the fields are serialized.

@JsonManagedReference and @JsonBackReference

The @JsonManagedReference and @JsonBackReference annotation are used to create JSON structures that have a bidirectional relationship. Without this annotation, you get an error like this.

Let us consider an example Java class that uses the @JsonManagedReference and @JsonBackReference annotations.

ManagedReferenceDemoBean.java

BackReferenceDemoBean.java

The test code to test both @JsonManagedReference and @JsonBackReference annotations is this.

The output of running the test in IntelliJ is this.
@BackReferenceDemoBean and @ManagedReferenceDemoBean Test Output

As you can see, the field marked with @JsonManagedReference is the forward reference which will be included during serialization. The field marked with @JsonBackReference is the back reference and is usually omitted during serialization.

@JsonIdentityInfo

The @JsonIdentityInfo tells Jackson to perform serialization or deserialization using the identity of the object. This annotation works similar to the @JsonManagedReference and @JsonBackReference annotations with the difference that @JsonIdentityInfo includes the back reference object.

Let us consider an example where the IdentityInfoEmployeeDemoBean has a bidirectional relationship with IdentityInfoManagerDemoBean using the @JsonIdentityInfo annotation.

IdentityInfoEmployeeDemoBean.java

IdentityInfoManagerDemoBean.java

The test code to test the @JsonIdentityInfo annotation is this.

The output of running the test in IntelliJ is this.
@JsonIdentityInfo Test Output

As you can see, the output gives the information about the employee with his manager details. It also provides the additional information about the employees under the manager.

@JsonFilter

The @JsonFilter annotation is used to tell Jackson to use a custom defined filter to serialize the Java object. To define your filter, you need to use the FilterProvider class. This provider gets the actual filter instance to use. The filter is then configured by assigning the FilterProvider to ObjectMapper.

Let us consider an example of Java class that uses the @JsonFilter annotation.

FilterDemoBean.java

The test code to test the @JsonFilter annotation is this.

The output of running the test in IntelliJ is this.

@JsonFilter Test Output
As you can see, the custom filter declared as the arguments of the @JsonFilter annotation extract only the name and filters out the other properties of the bean during serialization.

You can download the source code of this post from here.

0
Share

GSON is a very popular Java library for work with JSON.

JavaScript Object Notation (JSON) is a lightweight data exchange format. Like XML, JSON provides a way of representing object that is both human readable and machine processable.

JSON is the most commonly used data exchange format on the Web. In the Java ecosystem, several libraries which that you can use to serialize Java objects to JSON, transmit the JSON data over a network, and deserialize the JSON back to Java objects.

In this post, we’ll take a look at using the GSON library, which stands for Google JSON.

The Maven POM

In order to use GSON, you need the JAR files of the GSON library in your project classpath. If you are using Maven, include the GSON dependency in your Maven POM.

The code to add the GSON dependency is this:

The POJO

For the sample application, let’s create a Product POJO with few fields to represent product information.

Here is the code of the Product class.

Product.java

Converting Java Objects to JSON Representations

Before you start using GSON in your application, you need to first create an instance of Gson. There are two ways to do so:

  • Use the Gson class to create a new instance.
  • Create a GsonBuilder instance and call the create() method on it.

Use the GsonBuilder when you want to configure your Gson object. Otherwise, the Gson class will itself serve you.

Once you have a Gson object, you can call the toJson() method. This method takes a Java object and returns the corresponding JSON, as a String.

The following code shows how to covert the Product POJO into JSON.

Here is a unit test to test the simpleJSON() method.

Above, I am using JUnit as the test framework. If you are new to JUnit, I checkout my series of posts on Unit Testing using JUnit.

The output on running the test in IntelliJ is this.