One common requirement in Java application is to iterate through the elements of a collection. Prior to Java 8, the three most common ways to iterate through a collection are by using the while loop, for loop, and enhanced for loop. As the Java Collection interface extends Iterable, you can also use the hasNext() and next() methods of Iterable to iterate through collection elements.

Starting from Java 8, we have a new forEach method in Iterable to loop through elements in a collection – but in a different way.

In this post, I will discuss the  forEach method introduced in Java 8.

External vs Internal Iterators

Based on who controls iterations, Java Iterators can be classified into external and internal iterators.

External iterators are also known as active or explicit iterators. When using an external iterator, the client code performing the iteration controls the iteration. The client creates the iterator and instructs it when to advance to the next element. The client also checks whether or not all the element has been visited, and so on.

Enumerations, iterators, and enhanced for-loop are all examples of external iterators. Remember the old hasMoreElements() and nextElement() of Enumeration that you write to control iteration? Similarly, next() and hasNext() of Iterator?

The enhanced for loop introduced in Java 5 is another example of external iterator. An example of the enhanced for loop is this.

As evident from this code, the enhanced for loop shields developers from explicitly controlling looping via code. However, internally the next() and hasNext() methods get called, and therefor making it an external iterator.

Internal iterators are also known as passive, implicit or callback iterator. When you use an internal iterator, it is the iterator itself that controls the iteration. The client code essentially says to the iterator, “perform this operation on the elements in the collection.

Internal iterator has been introduced in Java 8 with the introduction of Lambda expression. The forEach method of this post covers is an internal iterator.

List Iteration using Java 8 forEach

The code to iterate through the elements of a list using forEach is this.

This code declaratively states what is meant to be done with the elements of the List. The internal iterator manages the iterations in the background.

To make the code clearer, the same iterateThroughList() method can be written using method reference like this.

You can test the code with this.

The output of the code in the IntelliJ console is this.
forEach List Iteration

Inside Java 8 forEach

In the example we just saw, we used lambda expressions. Let us dissect the forEach method and look what is happening inside.

The signature of the forEach method is this.

The forEach method performs the given action for each element of the Iterable until all elements have been processed or the action throws an exception. The Consumer parameter of forEach is a functional interface with the accept(Object) method.

We can therefore rewrite the previous iterateThroughList() method like this.

This code uses an anonymous class to instantiate a Consumer implementation. The Consumer instance is then passed as an argument to forEach. This code will produce the same result as the lambda expression we wrote.

Map Iteration using Java 8 forEach

Map in Java does not extends Iterable and therefore does not inherit Iterable’s forEach. However, Map itself has its own forEach method that you can use to iterate through key-value pairs.

The following code uses a lambda expression to do so.

You can test the code, with this.

The output of the code in the IntelliJ console is this.
forEach Map Iteration

Stream Iteration using Java 8 forEach

With both the new forEach method and the Java 8 Stream API, you can create a stream of elements in a collection and then pipeline the stream to a forEach method for iteration.

The code to iterate through a stream of elements in a List is this.

The code to test this method is this.

The output of the code is this.

For parallel streams, the only difference is that you need to call the parallelStream() method instead of stream() on the List. Then iterate through the stream of elements using forEach, like this.

The code to test this method is this.

The output of the code is this.
forEach Parallel Stream Iteration

As you can notice, the order in which the list elements are processed is not the order in which the elements are stored in the list. However, when dealing with larger sets of data, parallel streams bring in considerable performance gain to your program.

Conclusion

The new forEach method of Java 8 brings in a more declarative approach to iteration. As a developer, you write code to specify the result rather than how to compute it.

This new declarative approach is more readable but also less error prone.

In addition, the forEach() method fits intuitively with the Stream API and particularly makes using parallel streams easy.

0
Share

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

0
Share
, , ,

When developing Spring Boot applications, you need to tell the Spring Framework where to look for Spring components. Using component scan is one method of asking Spring to detect Spring managed components. Spring needs the information to locate and register all the Spring components with the application context when the application starts.

Spring can auto scan, detect, and instantiate components from pre-defined project packages. Spring can auto scan all classes annotated with the stereotype annotations @Component, @Controller, @Service, and @Repository

In this post, I will discuss how Spring component scanning works.

Sample Application

Let us create a simple Spring Boot application to understand how component scanning works in Spring.

We will start by writing few components.

DemoBeanA.java

DemoBeanB1.java

DemoBeanB2.java

DemoBeanB3.java

DemoBeanC.java

DemoBeanD.java

The @SpringBootApplication Annotation

Spring needs to know which packages to scan for annotated components in order to add them to the IoC container. In a Spring Boot project, we typically set the main application class with the @SpringBootApplication annotation. Under the hood, @SpringBootApplication is a composition of the @Configuration, @ComponentScan, and @EnableAutoConfiguration annotations. With this default setting, Spring Boot will auto scan for components in the current package (containing the @SpringBoot main class) and its sub packages.

To know more about these annotations go through my Spring Framework Annotations post.

Note: It is recommended that you locate your main application class in a root package above the component classes of the application.

The code to create the main class and access components is this.

BlogPostsApplication.java

The output of running the main class is this.
Output of BlogPostsApplication.java class

As you can notice, all the classes in the sub packages of the main class BlogPostsApplication are auto scanned by Spring.

@ComponentScan – Identifying Base Packages

The @ComponentScan annotation is used with the @Configuration annotation to tell Spring the packages to scan for annotated components. @ComponentScan also used to specify base packages and base package classes using thebasePackageClasses or basePackages attributes of @ComponentScan.

The basePackageClasses attribute is a type-safe alternative to basePackages. When you specify basePackageClasses, Spring will scan the package (and subpackages) of the classes you specify. 

A Java class annotated with @ComponentScan with the basePackageClassesattribute is this.

BlogPostsApplicationWithComponentScan.java

The output on running the main class is this.
Output of BlogPostsApplicationWithComponentScan.java Class

The @ComponentScan annotation uses the basePackages attribute to specify three packages (and subpackages) that will be scanned by Spring. The annotation also uses the basePackageClasses attribute to declare the DemoBeanB1 class whose package Spring Boot should scan.

As demoBeanC is in a different package, Spring did not find it during component scanning.

Component Scanning Filters

You can configure component scanning by using different type filters that Spring provides.

By using filters, you can further narrow the set of candidate components from everything in basePackages to everything in the base packages that matches the given filter or filters.

Filters can be of two types: include and exclude filters. As their names suggest, include filters specify which types are eligible for component scanning, while exclude filters specify which types are not.

You can use the include and/or exclude filters with or without the default filter. To disable the default filter, set the useDefaultFilters element of the @ComponentScan annotation to false.

The code to disable the default filter is this.

BlogPostsApplicationDisablingDefaultFilters.java

In the preceding code, the value member defines the specific guru.springframework.blog.componentscan.example.demopackageA package to scan, while the useDefaultFilters member disables the default filter.

The output on running the main class is this.
Output of BlogPostsApplicationDisablingDefaultFilters.java Class

As you can notice, the class DemoBeanA in the package demopackageA is unavailable when the useDefaultFilters element of the @ComponentScan annotation is set to false.

Component Scanning Filter Types

Spring provides the FilterType enumeration for the type filters that may be used in conjunction with @ComponentScan.

The available FilterType values are:

  • FilterType.ANNOTATION: Include or exclude those classes with a stereotype annotation
  • FilterType.ASPECTJ: Include or exclude classes using an AspectJ type pattern expression
  • FilterType.ASSIGNABLE_TYPE: Include or exclude classes that extend or implement this class or interface
  • FilterType.REGEX: Include or exclude classes using a regular expression
  • FilterType.CUSTOM: Include or exclude classes using a custom implementation of the org.springframework.core.type.TypeFilter interface

Include Filters

With include filters, you can include certain classes to be scanned by Spring. To include assignable type, use the includeFilters element of the @ComponentScan annotation with FilterType. ASSIGNABLE_TYPE. Using this filter, you can instruct Spring to scan for classes that extends or implements the class or interface you specify.

The code to use the includeFilters element of @ComponentScan is this.

BlogPostsApplicationIncludeFilter.java

The output on running the main class is this.
Output of BlogPostsApplicationIncludeFilter.java Class

As shown in the preceding figure, Spring detected and used the demoBean3 component that extends demoBean2.

Include Filters using Regex

You can use regular expressions to filter out components to be scanned by Spring. Use the includeFiltersnested annotation @ComponentScan.Filter type FilterType.REGEXto set a pattern.

The code to use an exclude filter based on regular expression is this.

BlogPostsApplicationFilterTypeRegex.java

The output of the following code snippet is this.
Output of BlogPostsApplicationFilterTypeRegex.java Class
As shown in the preceding figure, the classes whose names end with A, or 2 are detected by Spring.

Exclude Filters

The @ComponentScan annotation enables you to exclude those classes that you do not want to scan.

The code to use an exclude filter is this.

BlogPostsApplicationExcludeFilter.java

In this code, the nested annotation @ComponentScan.Filter is used to specify the filter type as FilterType.ASSIGNABLE_TYPE and the base class that should be excluded from scanning.

The output is this.
Output of using the FilterType.ASSIGNABLE_TYPE type

As you can see, the class DemoBeanB2 has been excluded from being scanned.

Summary

When using Spring Boot, most of the time the default auto scanning will work for your project. You only need to ensure that your @SpringBoot main class is at the base package of your package hierarchy. Spring Boot will automatically perform a component scan in the package of the Spring Boot main class and below.

One related annotation that I didn’t mention in this post is @EntityScan is more about JPA entity scanning rather than component scanning. The @EntityScan annotation, unlike @ComponentScan does not create beans. It only identifies which classes should be used by a specific persistence context.

2
Share

While developing applications, we often need to generate random numbers. Java provides support to generate random numbers primarily through the java.lang.Math and java.util.Random classes.

In this post, I will discuss different ways to generate random numbers based on different types of requirements.

Random Numbers using the Math Class

Java provides the Math class in the java.util package to generate random numbers.

The Math class contains the static Math.random()method to generate random numbers of double type.
The random() method returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0. When you call Math.random(), under the hood, a java.util.Random pseudorandom-number generator object is created and used.

You can use the Math.random() method with or without passing parameters. If you provide parameters, the method produces random numbers within the given parameters.

The code to use the Math.random() method is this.

The getRandomNumber() method uses the Math.random() method to return a positive double value, that is greater than or equal to 0.0 and less than 1.0.

The output of running the code is this.

Random Numbers within a Given Range

For generating random numbers between a given a range, you need to specify the range. A standard expression for accomplishing this is:

Let us break this expression into steps:

    1. First, multiply the magnitude of the range of values you want to cover by the result that Math.random() produces.
      Math.random() * ( max - min )This returns a value in the range [0, max min] where max is excluded. For example, if you want [5,10] you need to cover 5 integer values. So you can use Math.random()*5. This would return a value in the range [0,5], where 5 is not included.
    2. Next, shift this range up to the range that you are targeting. You do this by adding the min value.

(Math.random() * ( max - min )) + min

But, this still does not include the maximum value.

    1. To get the max value included, you need to add 1 to your range parameter (max - min). This will return a random double within the specified range.

double x = (Math.random()*((max-min)+1))+min;

There are different ways of implementing the above expression. Let us look at a couple of them.

Random Double within a Given Range

By default, the Math.random() method returns a random number of the type double whenever it is called. The code to generate a random double value between a specified range is this.

You can call the preceding method from the main method by passing the arguments like this.

The output is this.

Random Integer within a Given Range

The code to generate a random integer value between a specified range is this.

The preceding getRandomIntegerBetweenRange() method produces a random integer between the given range. As Math.random() method generates random numbers of double type, you need to truncate the decimal part and cast it to int in order to get the integer random number. You can call this method from the main method by passing the arguments as follow:

The output is this.

Note: You can pass a range of negative values to generate a random negative number within the range.

Random Number Generation using the Random Class

You can use the java.util.Random class to generate random numbers of different types, such as int, float, double, long, and boolean.

To generate random numbers, first, create an instance of the Random class and then call one of the random value generator methods, such as nextInt(), nextDouble(), or nextLong().

The nextInt() method of Random accepts a bound integer and returns a random integer from 0 (inclusive) to the specified bound (exclusive).

The code to use the nextInt() method is this.

The code to use the nextInt() method to generate an integer within a range is this.

The nextFloat() and nextDouble() methods allow generating float and double values between 0.0 and 1.0.

The code to use both the methods is this.

New Random Number Generation Features in Java 8

Java 8 has introduced a new method ints() in the java.util.Random class. The ints() method returns an unlimited stream of pseudorandom int values. You can limit the random numbers between a specified range by providing the minimum and the maximum values.

The code to use the Random.ints() method to generate random integer values within a specified range is this.

The getRandomNumberInts() method generates a stream of random integers between the min (inclusive) and max (exclusive). As ints() method produces an IntStream, the code calls the findFirst() method that returns an OptionalInt object that describes the first element of this stream. The code then calls the getAsInt()method to return the int value in OptionalInt.

The code to use the Random.ints() method to generate a stream of specified random integer values is this.

The code to call the preceding method is this.

The output of the preceding code is this.

The code to use the Random.ints() method to generate a stream of a specified number of random integer values between a range is this.

The code to call the preceding method is this.

The output of the preceding code is this.

In addition to ints(), some other frequently used methods that Java 8 introduces to the Random class which can return a sequential stream of random numbers are:

      • LongStream longs()
      • DoubleStream doubles()

Summary

The java.util.Random class implements what is generally called a linear congruential generator (LCG). It is designed to be fast but does not meet requirements for real-time use. For example, use in unique session ID generation on a web server, scientific experiments, cryptography, or lotteries and sweepstakes where monetary stake is involved. For such scenarios, there are other alternatives, which I will cover in a later post.

For the impatient readers, you can have a look at the SecureRandom class and Xorshift random number generators.

Also, an interesting resource is random.org, a true random number service that generates randomness via atmospheric noise.

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.