Jackson Annotations - Quick Guide



Jackson Annotations - Environment Setup

This chapter will guide you on how to prepare a development environment to start your work with Jackson Annotations. It will also teach you how to set up JDK on your machine before you set up GSON −

Setup Java Development Kit (JDK)

You can download the latest version of SDK from Oracle's Java site − Java SE Downloads. You will find instructions for installing JDK in downloaded files, follow the given instructions to install and configure the setup. Finally set PATH and JAVA_HOME environment variables to refer to the directory that contains java and javac, typically java_install_dir/bin and java_install_dir respectively.

If you are running Windows and have installed the JDK in C:\jdk-24, you would have to put the following line in your C:\autoexec.bat file.

set PATH=C:\jdk-24;%PATH% 
set JAVA_HOME=C:\jdk-24

Alternatively, on Windows NT/2000/XP, you will have to right-click on My Computer, select Properties → Advanced → Environment Variables. Then, you will have to update the PATH value and click the OK button.

On Unix (Solaris, Linux, etc.), if the SDK is installed in /usr/local/jdk-24 and you use the C shell, you will have to put the following into your .cshrc file.

setenv PATH /usr/local/jdk-24/bin:$PATH 
setenv JAVA_HOME /usr/local/jdk-24

Alternatively, if you use an Integrated Development Environment (IDE) like Borland JBuilder, Eclipse, IntelliJ IDEA, or Sun ONE Studio, you will have to compile and run a simple program to confirm that the IDE knows where you have installed Java. Otherwise, you will have to carry out a proper setup as given in the document of the IDE.

Popular Java Editors

To write your Java programs, you need a text editor. There are many sophisticated IDEs available in the market. But for now, you can consider one of the following −

  • Notepad − On Windows machine, you can use any simple text editor like Notepad (Recommended for this tutorial), TextPad.

  • Netbeans − It is a Java IDE that is open-source and free, which can be downloaded from www.netbeans.org/index.html.

  • Eclipse − It is also a Java IDE developed by the eclipse open-source community and can be downloaded from www.eclipse.org.

Jackson Environment

Download the latest version of jackson and related jar files.

At the time of writing this tutorial, we have copied them into C:\>Jackson folder.

OS Archive name
Windows jackson-core-2.20.0-rc1.jar;jackson-databind-2.20.0-rc1.jar;jackson-annotations-3.0-rc5.jar
Linux jackson-core-2.20.0-rc1.jar;jackson-databind-2.20.0-rc1.jar;jackson-annotations-3.0-rc5.jar
Mac jackson-core-2.20.0-rc1.jar;jackson-databind-2.20.0-rc1.jar;jackson-annotations-3.0-rc5.jar

Set CLASSPATH Variable

Set the CLASSPATH environment variable to point to the Guice jar location. Assuming, you have stored Guice and related jars in Jackson folder on various Operating Systems as follows.

OS Output
Windows Set the environment variable CLASSPATH to %CLASSPATH%;C:\Jackson\jackson-core-2.20.0-rc1.jar;C:\Jackson\jackson-databind-2.20.0-rc1.jar;C:\Jackson\jackson-annotations-3.0-rc5.jar;
Linux export CLASSPATH=$CLASSPATH:Jackson/jackson-core-2.20.0-rc1.jar:Jackson/jackson-databind-2.20.0-rc1.jar:Jackson/jackson-annotations-3.0-rc5.jar:.
Mac export CLASSPATH=$CLASSPATH:Jackson/jackson-core-2.20.0-rc1.jar:Jackson/jackson-databind-2.20.0-rc1.jar:Jackson/jackson-annotations-3.0-rc5:.

Jackson Annotations - @JsonAnyGetter

Overview

@JsonAnyGetter annotation allows a getter method to return Map which is then used to serialize the additional properties of JSON in the similar fashion as other properties.

Example - Serialization without using @JsonAnyGetter

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException; 
import java.util.HashMap; 
import java.util.Map; 
import com.fasterxml.jackson.databind.ObjectMapper; 

public class JacksonTester { 
   public static void main(String args[]){
      ObjectMapper mapper = new ObjectMapper(); 
      try{
         Student student = new Student(); 
         student.add("Name", "Mark"); 
         student.add("RollNo", "1"); 
         String jsonString = mapper 
            .writerWithDefaultPrettyPrinter() 
            .writeValueAsString(student); 
         System.out.println(jsonString); 
      } 
      catch (IOException e) { 
         e.printStackTrace(); 
      }   
   }
}
class Student {
   private Map<String, String> properties; 
   public Student(){ 
      properties = new HashMap<>(); 
   } 
   public Map<String, String> getProperties(){ 
      return properties; 
   } 
   public void add(String property, String value){ 
      properties.put(property, value); 
   } 
}

Output

Run the JacksonTester and verify the output −

{
   "properties" : {
      "RollNo" : "1",
      "Name" : "Mark"
   } 
}

Example - Serialization with @JsonAnyGetter

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException; 
import java.util.HashMap; 
import java.util.Map; 
import com.fasterxml.jackson.annotation.JsonAnyGetter; 
import com.fasterxml.jackson.databind.ObjectMapper; 

public class JacksonTester {
   public static void main(String args[]){
      ObjectMapper mapper = new ObjectMapper();
      try{
         Student student = new Student(); 
         student.add("Name", "Mark"); 
         student.add("RollNo", "1"); 
         String jsonString = mapper 
            .writerWithDefaultPrettyPrinter() 
            .writeValueAsString(student); 
         System.out.println(jsonString); 
      }
      catch (IOException e) {
         e.printStackTrace();
      } 
   }
}
class Student {
   private Map<String, String> properties;
   public Student(){
      properties = new HashMap<>();
   }
   @JsonAnyGetter
   public Map<String, String> getProperties(){
      return properties;
   }
   public void add(String property, String value){
      properties.put(property, value);
   }
}

Output

Run the JacksonTester and verify the output −

{
   "RollNo" : "1",
   "Name" : "Mark"
}

Here we're utilizing the @JsonAnyGetter to treat the properties map to act as other properties of the object.

Jackson Annotations - @JsonGetter

Overview

@JsonAnyGetter annotation allows a specific method to be marked as getter method.

Example - Serialization without using @JsonGetter

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException; 
import com.fasterxml.jackson.databind.ObjectMapper; 

public class JacksonTester {
   public static void main(String args[]){
      ObjectMapper mapper = new ObjectMapper();
      try {
         Student student = new Student("Mark", 1);
         String jsonString = mapper 
            .writerWithDefaultPrettyPrinter()
            .writeValueAsString(student);
         System.out.println(jsonString);
      }
      catch (IOException e) {
         e.printStackTrace();
      }
   }
}
class Student {
   private String name;
   private int rollNo;
   public Student(String name, int rollNo){
      this.name = name;
      this.rollNo = rollNo;
   }  
   public String getStudentName(){
      return name;
   } 
   public int getRollNo(){
      return rollNo;
   }
}

Output

Run the JacksonTester and verify the output −

{
  "rollNo" : 1,
  "studentName" : "Mark"
}

Example - Serialization with @JsonGetter

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import com.fasterxml.jackson.databind.ObjectMapper; 
import com.fasterxml.jackson.annotation.JsonGetter; 

public class JacksonTester {
   public static void main(String args[]){ 
      ObjectMapper mapper = new ObjectMapper(); 
      try {
         Student student = new Student("Mark", 1);    
         String jsonString = mapper 
            .writerWithDefaultPrettyPrinter() 
            .writeValueAsString(student); 
         System.out.println(jsonString); 
      } 
      catch (IOException e) { 
         e.printStackTrace();  
      }   
   }
}
class Student {
   private String name;
   private int rollNo;
   public Student(String name, int rollNo){
      this.name = name;
      this.rollNo = rollNo;
   }
   @JsonGetter
   public String getStudentName(){
      return name;
   }
   public int getRollNo(){
      return rollNo;
   }
}

Output

Run the JacksonTester and verify the output −

{
  "rollNo" : 1,
  "studentName" : "Mark"
}

Here we can see Jackson by default picks the getter of the Object. In case, we need to provide a custom getter method, we can use @JsonGetter annotation.

Jackson Annotations - @JsonPropertyOrder

Overview

@JsonPropertyOrder annotation allows a specific order to be preserved while serializing a JSON object.

Example - Serialization without using @JsonPropertyOrder

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]){
      ObjectMapper mapper = new ObjectMapper();
      try {
         Student student = new Student("Mark", 1);
         String jsonString = mapper
            .writerWithDefaultPrettyPrinter()
            .writeValueAsString(student);
         System.out.println(jsonString);
      }
      catch (IOException e) {
         e.printStackTrace();
      }
   }
}
class Student {
   private String name;
   private int rollNo;
   public Student(String name, int rollNo) {
      this.name = name;
      this.rollNo = rollNo;
   }
   public String getName(){
      return name;
   }
   public int getRollNo(){
      return rollNo; 
   }
}

Output

Run the JacksonTester and verify the output −

{
   "name" : "Mark",
   "rollNo" : 1
} 

Example - Serialization with @JsonPropertyOrder

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

public class JacksonTester {
   public static void main(String args[]){
      ObjectMapper mapper = new ObjectMapper();
      try {
         Student student = new Student("Mark", 1);
         String jsonString = mapper
            .writerWithDefaultPrettyPrinter()
            .writeValueAsString(student);
         System.out.println(jsonString);
      }
      catch (IOException e) {
         e.printStackTrace();
      }
   }
}
@JsonPropertyOrder({ "rollNo", "name" })
class Student {
   private String name; 
   private int rollNo; 
   public Student(String name, int rollNo){ 
      this.name = name; 
      this.rollNo = rollNo; 
   }  
   public String getName(){ 
      return name; 
   } 
   public int getRollNo(){ 
      return rollNo; 
   }  
}

Output

Run the JacksonTester and verify the output −

{
  "rollNo" : 1,
  "name" : "Mark"
}

Jackson Annotations - @JsonRawValue

Overview

@JsonRawValue annotation allows to serialize a text without escaping or without any decoration.

Example - Serialization without using @JsonRawValue

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException; 
import com.fasterxml.jackson.databind.ObjectMapper; 

public class JacksonTester {
   public static void main(String args[]){
      ObjectMapper mapper = new ObjectMapper();
      try {
         Student student = new Student("Mark", 1, "{\"attr\":false}");    
         String jsonString = mapper 
            .writerWithDefaultPrettyPrinter() 
            .writeValueAsString(student); 
         System.out.println(jsonString); 
      }
      catch (IOException e) { 
         e.printStackTrace(); 
      }   
   }
}
class Student { 
   private String name; 
   private int rollNo; 
   private String json;  
   public Student(String name, int rollNo, String json){
      this.name = name; 
      this.rollNo = rollNo; 
      this.json = json; 
   }  
   public String getName(){ 
      return name; 
   } 
   public int getRollNo(){ 
      return rollNo; 
   } 
   public String getJson(){ 
      return json; 
   }  
}

Output

Run the JacksonTester and verify the output −

{ 
   "name" : "Mark", 
   "rollNo" : 1, 
   "json" : {\"attr\":false} 
} 

Example - Serialization with @JsonRawValue

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException; 
import com.fasterxml.jackson.databind.ObjectMapper; 
import com.fasterxml.jackson.annotation.JsonRawValue; 

public class JacksonTester {
   public static void main(String args[]){
      ObjectMapper mapper = new ObjectMapper(); 
      try {
         Student student = new Student("Mark", 1, "{\"attr\":false}");    
         String jsonString = mapper 
            .writerWithDefaultPrettyPrinter() 
            .writeValueAsString(student); 
         System.out.println(jsonString); 
      }
      catch (IOException e) { 
         e.printStackTrace(); 
      }   
   }
}
class Student { 
   private String name; 
   private int rollNo;
   @JsonRawValue  
   private String json;  
   public Student(String name, int rollNo, String json) {
      this.name = name; 
      this.rollNo = rollNo; 
      this.json = json; 
   }  
   public String getName(){ 
      return name; 
   } 
   public int getRollNo(){ 
      return rollNo; 
   } 
   public String getJson(){ 
      return json; 
   }  
} 

Output

Run the JacksonTester and verify the output −

{ 
   "name" : "Mark", 
   "rollNo" : 1, 
   "json" : {"attr":false} 
}

Here we're using @JsonRawValue annotation over json property to escape special characters as evident in the output.

Jackson Annotations - @JsonValue

Overview

@JsonValue annotation allows to serialize an entire object using its single method.

Example - Serialization without using @JsonValue

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException; 
import com.fasterxml.jackson.annotation.JsonValue; 
import com.fasterxml.jackson.databind.ObjectMapper; 

public class JacksonTester {
   public static void main(String args[]){
      ObjectMapper mapper = new ObjectMapper(); 
      try { 
         Student student = new Student("Mark", 1);    
         String jsonString = mapper 
            .writerWithDefaultPrettyPrinter() 
            .writeValueAsString(student); 
         System.out.println(jsonString); 
      }
      catch (IOException e) { 
         e.printStackTrace(); 
      }   
   }
}
class Student {
   private String name;
   private int rollNo;
   public Student(String name, int rollNo){
      this.name = name;
      this.rollNo = rollNo;
   }
   public String getName(){
      return name;
   } 
   public int getRollNo(){
      return rollNo;
   }
   public String toString(){
      return "{ name : " + name + " }";
   }
}

Output

Run the JacksonTester and verify the output −

{
  "name" : "Mark",
  "rollNo" : 1
}

Example - Serialization with @JsonValue

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException; 
import com.fasterxml.jackson.annotation.JsonValue; 
import com.fasterxml.jackson.databind.ObjectMapper; 

public class JacksonTester {
   public static void main(String args[]){
      ObjectMapper mapper = new ObjectMapper(); 
      try { 
         Student student = new Student("Mark", 1);    
         String jsonString = mapper 
            .writerWithDefaultPrettyPrinter() 
            .writeValueAsString(student); 
         System.out.println(jsonString); 
      }
      catch (IOException e) { 
         e.printStackTrace(); 
      }   
   }
}
class Student {
   private String name;
   private int rollNo;
   public Student(String name, int rollNo){
      this.name = name;
      this.rollNo = rollNo;
   }
   public String getName(){
      return name;
   } 
   public int getRollNo(){
      return rollNo;
   }
   @JsonValue
   public String toString(){
      return "{ name : " + name + " }";
   }
}

Output

Run the JacksonTester and verify the output −

"{ name : Mark }" 

Here using @JsonValue annotation, we've controlled the default Serialization by toString() method.

Jackson Annotations - @JsonRootName

Overview

@JsonRootName annotation allows to have a root node specified over the JSON. We need to enable wrap root value as well.

Example - Serialization without using @JsonRootName

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;  
import com.fasterxml.jackson.databind.ObjectMapper; 

public class JacksonTester {
   public static void main(String args[]){ 
      ObjectMapper mapper = new ObjectMapper(); 
      try {
         Student student = new Student("Mark", 1);
         String jsonString = mapper 
            .writerWithDefaultPrettyPrinter() 
            .writeValueAsString(student); 
         System.out.println(jsonString); 
      }
      catch (IOException e) { 
         e.printStackTrace(); 
      }   
   }
}
class Student {
   private String name; 
   private int rollNo; 
   public Student(String name, int rollNo){ 
      this.name = name; 
      this.rollNo = rollNo; 
   }  
   public String getName(){ 
      return name; 
   } 
   public int getRollNo(){ 
      return rollNo; 
   }  
}

Output

Run the JacksonTester and verify the output −

{
  "name" : "Mark",
  "rollNo" : 1
}

Example - Serialization with @JsonRootName

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException; 
import com.fasterxml.jackson.annotation.JsonRootName; 
import com.fasterxml.jackson.databind.ObjectMapper; 
import com.fasterxml.jackson.databind.SerializationFeature; 

public class JacksonTester {
   public static void main(String args[]){ 
      ObjectMapper mapper = new ObjectMapper(); 
      try {
         Student student = new Student("Mark", 1);  
         mapper.enable(SerializationFeature.WRAP_ROOT_VALUE); 
         String jsonString = mapper 
            .writerWithDefaultPrettyPrinter() 
            .writeValueAsString(student); 
         System.out.println(jsonString); 
      }
      catch (IOException e) { 
         e.printStackTrace(); 
      }   
   }
}
@JsonRootName(value = "student") 
class Student {
   private String name; 
   private int rollNo; 
   public Student(String name, int rollNo){ 
      this.name = name; 
      this.rollNo = rollNo; 
   }  
   public String getName(){ 
      return name; 
   } 
   public int getRollNo(){ 
      return rollNo; 
   }  
}

Output

Run the JacksonTester and verify the output −

{ 
   "student" : { 
      "name" : "Mark", 
      "rollNo" : 1 
   } 
}

Here we've enabled root node by using ObjectMapper.enable(SerializationFeature.WRAP_ROOT_VALUE). By default, it prints the root name as class name as "Student". We've customized the root name using @JsonRootName annotation.

Jackson Annotations - @JsonSerialize

Overview

@JsonSerialize annotation is used to specify custom serializer to marshall the json object.

Example - Serialization without using @JsonSerialize

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException; 
import java.text.ParseException; 
import java.text.SimpleDateFormat; 
import java.util.Date; 

import com.fasterxml.jackson.core.JsonGenerator; 
import com.fasterxml.jackson.databind.ObjectMapper; 
import com.fasterxml.jackson.databind.SerializerProvider; 
import com.fasterxml.jackson.databind.annotation.JsonSerialize; 
import com.fasterxml.jackson.databind.ser.std.StdSerializer; 

public class JacksonTester {
   public static void main(String args[]) throws ParseException {
      ObjectMapper mapper = new ObjectMapper(); 
      SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy"); 
      try {
         Student student = new Student("Mark", 1, dateFormat.parse("20-11-1984")); 
         String jsonString = mapper 
            .writerWithDefaultPrettyPrinter() 
            .writeValueAsString(student); 
         System.out.println(jsonString); 
      } 
      catch (IOException e) { 
         e.printStackTrace(); 
      }   
   }
}
class Student {
   private String name; 
   private int rollNo; 
   private Date dateOfBirth; 
   public Student(String name, int rollNo, Date dob){ 
      this.name = name; 
      this.rollNo = rollNo; 
      this.dateOfBirth = dob; 
   }
   public String getName(){
      return name;
   }
   public int getRollNo(){
      return rollNo; 
   }
   public Date getDateOfBirth(){ 
      return dateOfBirth; 
   }
}

Output

Run the JacksonTester and verify the output −

{
  "name" : "Mark",
  "rollNo" : 1,
  "dateOfBirth" : 469737000000
}

Example - Serialization with @JsonSerialize

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException; 
import java.text.ParseException; 
import java.text.SimpleDateFormat; 
import java.util.Date; 

import com.fasterxml.jackson.core.JsonGenerator; 
import com.fasterxml.jackson.databind.ObjectMapper; 
import com.fasterxml.jackson.databind.SerializerProvider; 
import com.fasterxml.jackson.databind.annotation.JsonSerialize; 
import com.fasterxml.jackson.databind.ser.std.StdSerializer; 

public class JacksonTester {
   public static void main(String args[]) throws ParseException {
      ObjectMapper mapper = new ObjectMapper(); 
      SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy"); 
      try {
         Student student = new Student("Mark", 1, dateFormat.parse("20-11-1984")); 
         String jsonString = mapper 
            .writerWithDefaultPrettyPrinter() 
            .writeValueAsString(student); 
         System.out.println(jsonString); 
      } 
      catch (IOException e) { 
         e.printStackTrace(); 
      }   
   }
}
class Student {
   private String name; 
   private int rollNo; 
   @JsonSerialize(using = CustomDateSerializer.class) 
   private Date dateOfBirth; 
   public Student(String name, int rollNo, Date dob){ 
      this.name = name; 
      this.rollNo = rollNo; 
      this.dateOfBirth = dob; 
   }
   public String getName(){
      return name;
   }
   public int getRollNo(){
      return rollNo; 
   }
   public Date getDateOfBirth(){ 
      return dateOfBirth; 
   }
}
class CustomDateSerializer extends StdSerializer<Date> {
   private static final long serialVersionUID = 1L; 
   private static SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
   public CustomDateSerializer() { 
      this(null); 
   } 
   public CustomDateSerializer(Class<Date> t) { 
      super(t); 
   } 
   @Override 
   public void serialize(Date value, 
      JsonGenerator generator, SerializerProvider arg2) throws IOException { 
      generator.writeString(formatter.format(value)); 
   } 
}

Output

Run the JacksonTester and verify the output −

{
  "name" : "Mark",
  "rollNo" : 1,
  "dateOfBirth" : "20-11-1984"
}

Here we can compare the output, as date serialization is customized using CustomDateSerializer object put in use by @JsonSerialize annotation.

Jackson Annotations - @JsonCreator

Overview

@JsonCreator annotation is used to fine tune the constructor or factory method used in deserialization. We'll be using @JsonProperty as well to achieve the same. In the example below, we are matching an json with different format to our class by defining the required property names.

Example - Deserialization without using @JsonCreator

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException; 
import java.text.ParseException; 
 
import com.fasterxml.jackson.databind.ObjectMapper; 

public class JacksonTester {
   public static void main(String args[]) throws ParseException{ 
      String json = "{\"id\":1,\"theName\":\"Mark\"}"; 
      ObjectMapper mapper = new ObjectMapper();    
      try {
         Student student = mapper 
            .readerFor(Student.class) 
            .readValue(json); 
         System.out.println(student.rollNo +", " + student.name); 
      }
      catch (IOException e) { 
         e.printStackTrace(); 
      }
   }
}
class Student {
   public String name; 
   public int rollNo; 

   public Student(String name, int rollNo){
      this.name = name; 
      this.rollNo = rollNo; 
   }
}

Output

Run the JacksonTester and verify the output −

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of 'com.tutorialspoint.Student' (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: REDACTED ('StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION' disabled); line: 1, column: 2]
	at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
	at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1942)
	at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:415)
	at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1429)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1514)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:340)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
	at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:342)
	at com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:2130)
	at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1565)
	at com.tutorialspoint.JacksonTester.main(JacksonTester.java:15)

Example - Deserialization with @JsonCreator

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException; 
import java.text.ParseException; 

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

public class JacksonTester {
   public static void main(String args[]) throws ParseException{ 
      String json = "{\"id\":1,\"theName\":\"Mark\"}"; 
      ObjectMapper mapper = new ObjectMapper();    
      try {
         Student student = mapper 
            .readerFor(Student.class) 
            .readValue(json); 
         System.out.println(student.rollNo +", " + student.name); 
      }
      catch (IOException e) { 
         e.printStackTrace(); 
      }
   }
}
class Student {
   public String name; 
   public int rollNo; 

   @JsonCreator 
   public Student(@JsonProperty("theName") String name, @JsonProperty("id") int rollNo){
      this.name = name; 
      this.rollNo = rollNo; 
   }
}

Output

Run the JacksonTester and verify the output −

1, Mark 

Here we can see easily, that in case of custom JSON, Jackson throws exception. To handle custom JSON, we can customize deserialization using @JsonCreator and @JsonProperty.

Jackson Annotations - @JacksonInject

Overview

@JacksonInject annotation is used when a property value is to be injected instead of being parsed from Json input. In the example below, we are to insert a value into object instead of parsing from the Json.

Example - Deserialization without using @JacksonInject

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException; 
import java.text.ParseException; 

import com.fasterxml.jackson.databind.ObjectMapper; 

public class JacksonTester {
   public static void main(String args[]) throws ParseException{ 
      String json = "{\"name\":\"Mark\"}"; 
      
      ObjectMapper mapper = new ObjectMapper();    
      try {
         Student student = mapper 
            .readerFor(Student.class) 
            .readValue(json); 
         System.out.println(student.rollNo +", " + student.name); 
      }
      catch (IOException e) { 
         e.printStackTrace(); 
      }   
   }
}
class Student {
   public String name; 
   public int rollNo;  
}

Output

Run the JacksonTester and verify the output −

0, Mark

Example - Deserialization with @JacksonInject

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException; 
import java.text.ParseException; 

import com.fasterxml.jackson.annotation.JacksonInject; 
import com.fasterxml.jackson.databind.InjectableValues; 
import com.fasterxml.jackson.databind.ObjectMapper; 

public class JacksonTester {
   public static void main(String args[]) throws ParseException{ 
      String json = "{\"name\":\"Mark\"}"; 
      InjectableValues injectableValues = new InjectableValues.Std() 
         .addValue(int.class, 1); 
      
      ObjectMapper mapper = new ObjectMapper();    
      try {
         Student student = mapper 
            .reader(injectableValues) 
            .forType(Student.class) 
            .readValue(json); 
         System.out.println(student.rollNo +", " + student.name); 
      }
      catch (IOException e) { 
         e.printStackTrace(); 
      }   
   }
}
class Student {
   public String name; 
   @JacksonInject 
   public int rollNo;  
}

Output

Run the JacksonTester and verify the output −

1, Mark 

Here we can see, using @JacksonInject, we can a inject value in our object during deserialization easily.

Jackson Annotations - @JsonAnySetter

Overview

@JsonAnySetter annotation allows a setter method to use Map which is then used to deserialize the additional properties of JSON in the similar fashion as other properties.

Example - Deserialization without using @JsonAnySetter

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException; 
import java.util.HashMap; 
import java.util.Map; 

import com.fasterxml.jackson.databind.ObjectMapper; 

public class JacksonTester {
   public static void main(String args[]){ 
      ObjectMapper mapper = new ObjectMapper(); 
      String jsonString = "{\"RollNo\" : \"1\",\"Name\" : \"Mark\"}"; 
      try { 
         Student student = mapper.readerFor(Student.class).readValue(jsonString); 
         System.out.println(student.getProperties().get("Name")); 
         System.out.println(student.getProperties().get("RollNo")); 
      }
      catch (IOException e) {
         e.printStackTrace(); 
      } 
   }
}
class Student {
   private Map<String, String> properties; 
   public Student(){ 
      properties = new HashMap<>(); 
   }  
   public Map<String, String> getProperties(){ 
      return properties; 
   } 
   public void add(String property, String value){ 
      properties.put(property, value); 
   }   
}

Output

Run the JacksonTester and verify the output −

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "RollNo" (class com.tutorialspoint.Student), not marked as ignorable (one known property: "properties"])
 at [Source: REDACTED ('StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION' disabled); line: 1, column: 14] (through reference chain: com.tutorialspoint.Student["RollNo"])
	at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61)
	at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:1207)
	at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:2295)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1823)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1801)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:308)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:169)
	at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:342)
	at com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:2130)
	at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1565)
	at com.tutorialspoint.JacksonTester.main(JacksonTester.java:14)

Example - Deserialization with @JsonAnySetter

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException; 
import java.util.HashMap; 
import java.util.Map; 

import com.fasterxml.jackson.annotation.JsonAnySetter; 
import com.fasterxml.jackson.databind.ObjectMapper; 

public class JacksonTester {
   public static void main(String args[]){ 
      ObjectMapper mapper = new ObjectMapper(); 
      String jsonString = "{\"RollNo\" : \"1\",\"Name\" : \"Mark\"}"; 
      try { 
         Student student = mapper.readerFor(Student.class).readValue(jsonString); 
         System.out.println(student.getProperties().get("Name")); 
         System.out.println(student.getProperties().get("RollNo")); 
      }
      catch (IOException e) {
         e.printStackTrace(); 
      } 
   }
}
class Student {
   private Map<String, String> properties; 
   public Student(){ 
      properties = new HashMap<>(); 
   }  
   public Map<String, String> getProperties(){ 
      return properties; 
   } 
   @JsonAnySetter 
   public void add(String property, String value){ 
      properties.put(property, value); 
   }   
}

Output

Run the JacksonTester and verify the output −

Mark 
1 

Here we can see, without using @JsonAnySetter, we get the exception during deserialization. Using @JsonAnySetter annotation, we can use map as properties of an object.

Jackson Annotations - @JsonSetter

Overview

@JsonSetter annotation allows a specific method to be marked as setter method.

Example - Deserialization without using @JsonSetter

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException; 
import com.fasterxml.jackson.annotation.JsonSetter; 
import com.fasterxml.jackson.databind.ObjectMapper; 

public class JacksonTester {
   public static void main(String args[]){ 
      ObjectMapper mapper = new ObjectMapper(); 
      String jsonString = "{\"rollNo\":1,\"name\":\"Marks\"}"; 

      try { 
         Student student = mapper.readerFor(Student.class).readValue(jsonString);
         System.out.println(student.getRollNo() + ", " + student.getName()); 
      }
      catch (IOException e) {
         e.printStackTrace(); 
      }   
   } 
}
class Student { 
   private int rollNo; 
   private String name; 
   public void setTheName(String name) { this.name = name; } 
   public void setTheRollNo(int rollNo) {this.rollNo = rollNo;}
   public int getRollNo() {return rollNo;}
   public String getName() {return name;}
}

Output

Run the JacksonTester and verify the output −

1, Marks

Example - Deserialization with @JsonSetter

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException; 
import com.fasterxml.jackson.annotation.JsonSetter; 
import com.fasterxml.jackson.databind.ObjectMapper; 

public class JacksonTester {
   public static void main(String args[]){ 
      ObjectMapper mapper = new ObjectMapper(); 
      String jsonString = "{\"rollNo\":1,\"name\":\"Marks\"}"; 

      try { 
         Student student = mapper.readerFor(Student.class).readValue(jsonString);
         System.out.println(student.getRollNo() + ", " + student.getName()); 
      }
      catch (IOException e) {
         e.printStackTrace(); 
      }   
   } 
}
class Student { 
   private int rollNo; 
   private String name; 
   @JsonSetter("name") 
   public void setTheName(String name) { this.name = name; } 
   public void setTheRollNo(int rollNo) {this.rollNo = rollNo;}
   public int getRollNo() {return rollNo;}
   public String getName() {return name;}
}

Output

Run the JacksonTester and verify the output −

1, Marks

Here we can see, even without using @JsonSetter, Jackson handles the custom setter methods. But using @JsonSetter is recommended for custom setter methods.

Jackson Annotations - @JsonDeserialize

Overview

@JsonDeserialize annotation is used to specify custom deserializer to unmarshall the json object.

Example - Deserialization without using @JsonDeserialize

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import java.text.ParseException;
import java.util.Date;

import com.fasterxml.jackson.databind.ObjectMapper; 

public class JacksonTester {
   public static void main(String args[]) throws ParseException{ 
      ObjectMapper mapper = new ObjectMapper(); 
      String jsonString = "{\"name\":\"Mark\",\"dateOfBirth\":\"20-12-1984\"}"; 
      try {     
         Student student = mapper
            .readerFor(Student.class) 
            .readValue(jsonString); 
         System.out.println(student.dateOfBirth); 
      } 
      catch (IOException e) { 
         e.printStackTrace(); 
      }   
   }
}
class Student {
   public String name; 
   public Date dateOfBirth; 
}

Output

Run the JacksonTester and verify the output −

com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type 'java.util.Date' from String "20-12-1984": not a valid representation (error: Failed to parse Date value '20-12-1984': Cannot parse date "20-12-1984": not compatible with any of standard forms ("yyyy-MM-dd'T'HH:mm:ss.SSSX", "yyyy-MM-dd'T'HH:mm:ss.SSS", "EEE, dd MMM yyyy HH:mm:ss zzz", "yyyy-MM-dd"))
 at [Source: REDACTED ('StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION' disabled); line: 1, column: 30] (through reference chain: com.tutorialspoint.Student["dateOfBirth"])
	at com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:67)
	at com.fasterxml.jackson.databind.DeserializationContext.weirdStringException(DeserializationContext.java:2013)
	at com.fasterxml.jackson.databind.DeserializationContext.handleWeirdStringValue(DeserializationContext.java:1299)
	at com.fasterxml.jackson.databind.deser.std.StdDeserializer._parseDate(StdDeserializer.java:1426)
	at com.fasterxml.jackson.databind.deser.std.StdDeserializer._parseDate(StdDeserializer.java:1368)
	at com.fasterxml.jackson.databind.deser.std.DateDeserializers$DateBasedDeserializer._parseDate(DateDeserializers.java:200)
	at com.fasterxml.jackson.databind.deser.std.DateDeserializers$DateDeserializer.deserialize(DateDeserializers.java:302)
	at com.fasterxml.jackson.databind.deser.std.DateDeserializers$DateDeserializer.deserialize(DateDeserializers.java:280)
	at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:137)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:302)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:169)
	at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:342)
	at com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:2130)
	at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1565)
	at com.tutorialspoint.JacksonTester.main(JacksonTester.java:16)

Example - Deserialization with @JsonDeserialize

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException; 
import java.text.ParseException; 
import java.text.SimpleDateFormat; 
import java.util.Date; 

import com.fasterxml.jackson.core.JsonParser; 
import com.fasterxml.jackson.core.JsonProcessingException; 
import com.fasterxml.jackson.databind.DeserializationContext; 
import com.fasterxml.jackson.databind.ObjectMapper; 
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 
import com.fasterxml.jackson.databind.deser.std.StdDeserializer; 

public class JacksonTester {
   public static void main(String args[]) throws ParseException{ 
      ObjectMapper mapper = new ObjectMapper(); 
      String jsonString = "{\"name\":\"Mark\",\"dateOfBirth\":\"20-12-1984\"}"; 
      try {     
         Student student = mapper
            .readerFor(Student.class) 
            .readValue(jsonString); 
         System.out.println(student.dateOfBirth); 
      } 
      catch (IOException e) { 
         e.printStackTrace(); 
      }   
   }
}
class Student {
   public String name; 
   @JsonDeserialize(using = CustomDateDeserializer.class) 
   public Date dateOfBirth; 
}
class CustomDateDeserializer extends StdDeserializer<Date> {
   private static final long serialVersionUID = 1L;
   private static SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
   public CustomDateDeserializer() { 
      this(null); 
   } 
   public CustomDateDeserializer(Class t) { 
      super(t); 
   } 
   @Override 
   public Date deserialize(JsonParser parser, DeserializationContext context) 
      throws IOException, JsonProcessingException { 
      
      String date = parser.getText(); 
      try { 
         return formatter.parse(date); 
      } 
      catch (ParseException e) { 
         e.printStackTrace(); 
      }    
      return null; 
   }   
}

Output

Run the JacksonTester and verify the output −

Thu Dec 20 00:00:00 IST 1984

Here we can see, without using @JsonDeserialize, Jackson is unable to handle string deserialization to date. Using @JsonDeserialize we can define and set a custom deserializer for us.

Jackson Annotations - @JsonEnumDefaultValue

Overview

@JsonEnumDefaultValue annotation is used to deserialize an unknown enum value using a default value.

Example - Deserialization without using @JsonEnumDefaultValue

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException; 
import java.text.ParseException; 

import com.fasterxml.jackson.annotation.JsonEnumDefaultValue; 
import com.fasterxml.jackson.databind.DeserializationFeature; 
import com.fasterxml.jackson.databind.ObjectMapper; 

public class JacksonTester {
   public static void main(String args[]) throws ParseException{
      ObjectMapper mapper = new ObjectMapper();
      String jsonString = "\"abc\""; 
      try {
         LETTERS value = mapper.readValue(jsonString, LETTERS.class); 
         System.out.println(value); 
      }
      catch (IOException e) { 
         e.printStackTrace(); 
      }   
   }  
}
enum LETTERS {
   A, B 
} 

Output

Run the JacksonTester and verify the output −

com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type 'com.tutorialspoint.LETTERS' from String "abc": not one of the values accepted for Enum class: [A, B]
 at [Source: REDACTED ('StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION' disabled); line: 1, column: 1]
	at com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:67)
	at com.fasterxml.jackson.databind.DeserializationContext.weirdStringException(DeserializationContext.java:2013)
	at com.fasterxml.jackson.databind.DeserializationContext.handleWeirdStringValue(DeserializationContext.java:1299)
	at com.fasterxml.jackson.databind.deser.std.EnumDeserializer._deserializeAltString(EnumDeserializer.java:450)
	at com.fasterxml.jackson.databind.deser.std.EnumDeserializer._fromString(EnumDeserializer.java:307)
	at com.fasterxml.jackson.databind.deser.std.EnumDeserializer.deserialize(EnumDeserializer.java:272)
	at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:342)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4971)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3887)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3855)
	at com.tutorialspoint.JacksonTester.main(JacksonTester.java:13)

Example - Deserialization with @JsonEnumDefaultValue

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException; 
import java.text.ParseException; 

import com.fasterxml.jackson.annotation.JsonEnumDefaultValue; 
import com.fasterxml.jackson.databind.DeserializationFeature; 
import com.fasterxml.jackson.databind.ObjectMapper; 

public class JacksonTester {
   public static void main(String args[]) throws ParseException{
      ObjectMapper mapper = new ObjectMapper();
      mapper.enable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE);
      String jsonString = "\"abc\""; 
      try {
         LETTERS value = mapper.readValue(jsonString, LETTERS.class); 
         System.out.println(value); 
      }
      catch (IOException e) { 
         e.printStackTrace(); 
      }   
   }  
}
enum LETTERS {
   A, B, @JsonEnumDefaultValue UNKNOWN 
} 

Output

Run the JacksonTester and verify the output −

UNKNOWN

Here we can see, without using @JsonEnumDefaultValue, Jackson is unable to handle unknown enum value during deserialization. Using @JsonEnumDefaultValue we can define and set a default enum value for us.

Jackson Annotations - @JsonEnumDefaultValue

Overview

@JsonIgnoreProperties annotation is used at class level to mark a property or list of properties to be ignored.

Example - Serialization without using @JsonIgnoreProperties

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]) {
      ObjectMapper mapper = new ObjectMapper();
      try {
         Student student = new Student(1,11,"1ab","Mark");       
         String jsonString = mapper
            .writerWithDefaultPrettyPrinter()
            .writeValueAsString(student);
         System.out.println(jsonString);
      }
      catch (IOException e) { 
         e.printStackTrace();
      }   
   }
}
class Student {
   public int id;
   public String systemId;
   public int rollNo;
   public String name;

   Student(int id, int rollNo, String systemId, String name){
      this.id = id;
      this.systemId = systemId;
      this.rollNo = rollNo;
      this.name = name;
   }
}

Output

Run the JacksonTester and verify the output −

{
  "id" : 1,
  "systemId" : "1ab",
  "rollNo" : 11,
  "name" : "Mark"
}

Example - Serialization with @JsonIgnoreProperties

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]) {
      ObjectMapper mapper = new ObjectMapper();
      try {
         Student student = new Student(1,11,"1ab","Mark");       
         String jsonString = mapper
            .writerWithDefaultPrettyPrinter()
            .writeValueAsString(student);
         System.out.println(jsonString);
      }
      catch (IOException e) { 
         e.printStackTrace();
      }   
   }
}
@JsonIgnoreProperties({ "id", "systemId" })
class Student {
   public int id;
   public String systemId;
   public int rollNo;
   public String name;

   Student(int id, int rollNo, String systemId, String name){
      this.id = id;
      this.systemId = systemId;
      this.rollNo = rollNo;
      this.name = name;
   }
}

Output

Run the JacksonTester and verify the output −

{
  "rollNo" : 11,
  "name" : "Mark"
}

Here we can see, without using @JsonIgnoreProperties, Jackson is serializing all values by default. Using @JsonIgnoreProperties we can define the properties which are not to be serialized.

Jackson Annotations - @JsonIgnore

Overview

@JsonIgnore annotation is used at mark a property of special type to be ignored.

Example - Serialization without using @JsonIgnore

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]) {
      ObjectMapper mapper = new ObjectMapper();
      try {
         Student student = new Student(1,11,"1ab","Mark");       
         String jsonString = mapper
            .writerWithDefaultPrettyPrinter()
            .writeValueAsString(student);
         System.out.println(jsonString);
      }
      catch (IOException e) { 
         e.printStackTrace();
      }   
   }
}
class Student {
   public int id;
   public String systemId;
   public int rollNo;
   public String name;

   Student(int id, int rollNo, String systemId, String name){
      this.id = id;
      this.systemId = systemId;
      this.rollNo = rollNo;
      this.name = name;
   }
}

Output

Run the JacksonTester and verify the output −

{
  "id" : 1,
  "systemId" : "1ab",
  "rollNo" : 11,
  "name" : "Mark"
}

Example - Serialization with @JsonIgnore

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]){
      ObjectMapper mapper = new ObjectMapper();
      try{
         Student student = new Student(1,11,"1ab","Mark");       
         String jsonString = mapper
            .writerWithDefaultPrettyPrinter()
            .writeValueAsString(student);
         System.out.println(jsonString);
      }
      catch (IOException e) { 
         e.printStackTrace();
      }     
   }
}
class Student { 
   public int id;
   @JsonIgnore
   public String systemId;
   public int rollNo;
   public String name;

   Student(int id, int rollNo, String systemId, String name){
      this.id = id;
      this.systemId = systemId;
      this.rollNo = rollNo;
      this.name = name;
   }
}

Output

Run the JacksonTester and verify the output −

{
  "id" : 1,
  "rollNo" : 11,
  "name" : "Mark"
}

Here we can see, without using @JsonIgnore, Jackson is serializing all values by default. Using @JsonIgnore we can define the property which is to be ignored during serialization.

Jackson Annotations - @JsonIgnoreType

Overview

@JsonIgnoreType annotation is used at mark a property of special type to be ignored.

Example - Serialization without using @JsonIgnoreType

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]) {
      ObjectMapper mapper = new ObjectMapper();
      try {
         Student student = new Student(1,11,"1ab","Mark");       
         String jsonString = mapper
            .writerWithDefaultPrettyPrinter()
            .writeValueAsString(student);
         System.out.println(jsonString);
      }
      catch (IOException e) { 
         e.printStackTrace();
      }   
   }
}
class Student {
   public int id;
   public String systemId;
   public int rollNo;
   public String name;

   Student(int id, int rollNo, String systemId, String name){
      this.id = id;
      this.systemId = systemId;
      this.rollNo = rollNo;
      this.name = name;
   }
}

Output

Run the JacksonTester and verify the output −

{
  "id" : 1,
  "systemId" : "1ab",
  "rollNo" : 11,
  "nameObj" : {
    "name" : "Mark"
  }
}

Example - Serialization with @JsonIgnoreType

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import com.fasterxml.jackson.annotation.JsonIgnoreType;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]){
      ObjectMapper mapper = new ObjectMapper();
      try {
         Student student = new Student(1,11,"1ab","Mark");       
         String jsonString = mapper
            .writerWithDefaultPrettyPrinter()
            .writeValueAsString(student);
         System.out.println(jsonString);
      }
      catch (IOException e) { 
         e.printStackTrace();
      }     
   }
}
class Student { 
   public int id;
   public String systemId;
   public int rollNo;
   public Name nameObj;

   Student(int id, int rollNo, String systemId, String name){
      this.id = id;
      this.systemId = systemId;
      this.rollNo = rollNo;
      nameObj = new Name(name);
   }

   @JsonIgnoreType
   class Name {
      public String name;
      Name(String name){
         this.name = name;
      }       
   }
}

Output

Run the JacksonTester and verify the output −

{
  "id" : 1,
  "systemId" : "1ab",
  "rollNo" : 11
}

Here we can see, without using @JsonIgnoreType, Jackson is serializing all values by default including an inner class. Using @JsonIgnoreType we can define the properties of certain type which are to be ignored during serialization.

Jackson Annotations - @JsonInclude

Overview

@JsonInclude annotation is used to exclude properties having null/empty or default values.

Example - Serialization without using @JsonInclude

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]){
      ObjectMapper mapper = new ObjectMapper();
      try {
         Student student = new Student(1,null);       
         String jsonString = mapper
            .writerWithDefaultPrettyPrinter()
            .writeValueAsString(student);
         System.out.println(jsonString);
      }
      catch (IOException e) { 
         e.printStackTrace();
      }     
   }
}

class Student { 
   public int id; 
   public String name;

   Student(int id,String name){
      this.id = id;
      this.name = name;
   }   
}

Output

Run the JacksonTester and verify the output −

{
  "id" : 1,
  "name" : null
}

Example - Serialization with @JsonInclude

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]){
      ObjectMapper mapper = new ObjectMapper();
      try {
         Student student = new Student(1,null);       
         String jsonString = mapper
            .writerWithDefaultPrettyPrinter()
            .writeValueAsString(student);
         System.out.println(jsonString);
      }
      catch (IOException e) { 
         e.printStackTrace();
      }     
   }
}
@JsonInclude(JsonInclude.Include.NON_NULL)
class Student { 
   public int id; 
   public String name;

   Student(int id,String name){
      this.id = id;
      this.name = name;
   }   
}

Output

Run the JacksonTester and verify the output −

{
  "id" : 1
}

Here we can see, without using @JsonInclude, Jackson is serializing all values including null as well. Using @JsonInclude we can define the values which are to be ignored during serialization.

Jackson Annotations - @JsonAutoDetect

Overview

@JsonAutoDetect annotation is used to include properties which are not accessible otherwise.

Example - Serialization without using @JsonAutoDetect

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]){
      ObjectMapper mapper = new ObjectMapper();
      try{
         Student student = new Student(1,"Mark");       
         String jsonString = mapper
            .writerWithDefaultPrettyPrinter()
            .writeValueAsString(student);
         System.out.println(jsonString);
      }
      catch (IOException e) {
         e.printStackTrace();
      }     
   }
}

class Student { 
   private int id; 
   private String name;

   Student(int id,String name) {
      this.id = id;
      this.name = name;
   }   
}

Output

Run the JacksonTester and verify the output −

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class com.tutorialspoint.Student and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)
	at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
	at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1359)
	at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:415)
	at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:52)
	at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:29)
	at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:503)
	at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:342)
	at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1587)
	at com.fasterxml.jackson.databind.ObjectWriter._writeValueAndClose(ObjectWriter.java:1289)
	at com.fasterxml.jackson.databind.ObjectWriter.writeValueAsString(ObjectWriter.java:1140)
	at com.tutorialspoint.JacksonTester.main(JacksonTester.java:13)

Example - Serialization with @JsonAutoDetect

JacksonTester.java

package com.tutorialpoint;

import java.io.IOException;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]){
      ObjectMapper mapper = new ObjectMapper();
      try{
         Student student = new Student(1,"Mark");       
         String jsonString = mapper
            .writerWithDefaultPrettyPrinter()
            .writeValueAsString(student);
         System.out.println(jsonString);
      }
      catch (IOException e) {
         e.printStackTrace();
      }     
   }
}
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
class Student { 
   private int id; 
   private String name;

   Student(int id,String name) {
      this.id = id;
      this.name = name;
   }   
}

Output

Run the JacksonTester and verify the output −

{
  "id" : 1,
  "name" : "Mark"
}

Here we can see, without using @JsonAutoDetect, Jackson is unable to deserialize to private fields. Using @JsonAutoDetect we can include private fields which are not accessible during deserialization otherwise.

Jackson Annotations - @JsonAutoDetect

Overview

@JsonAutoDetect annotation is used to include properties which are not accessible otherwise.

Example - Serialization without using @JsonAutoDetect

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]){
      ObjectMapper mapper = new ObjectMapper();
      try{
         Student student = new Student(1,"Mark");       
         String jsonString = mapper
            .writerWithDefaultPrettyPrinter()
            .writeValueAsString(student);
         System.out.println(jsonString);
      }
      catch (IOException e) {
         e.printStackTrace();
      }     
   }
}

class Student { 
   private int id; 
   private String name;

   Student(int id,String name) {
      this.id = id;
      this.name = name;
   }   
}

Output

Run the JacksonTester and verify the output −

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class com.tutorialspoint.Student and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)
	at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
	at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1359)
	at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:415)
	at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:52)
	at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:29)
	at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:503)
	at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:342)
	at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1587)
	at com.fasterxml.jackson.databind.ObjectWriter._writeValueAndClose(ObjectWriter.java:1289)
	at com.fasterxml.jackson.databind.ObjectWriter.writeValueAsString(ObjectWriter.java:1140)
	at com.tutorialspoint.JacksonTester.main(JacksonTester.java:13)

Example - Serialization with @JsonAutoDetect

JacksonTester.java

package com.tutorialpoint;

import java.io.IOException;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]){
      ObjectMapper mapper = new ObjectMapper();
      try{
         Student student = new Student(1,"Mark");       
         String jsonString = mapper
            .writerWithDefaultPrettyPrinter()
            .writeValueAsString(student);
         System.out.println(jsonString);
      }
      catch (IOException e) {
         e.printStackTrace();
      }     
   }
}
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
class Student { 
   private int id; 
   private String name;

   Student(int id,String name) {
      this.id = id;
      this.name = name;
   }   
}

Output

Run the JacksonTester and verify the output −

{
  "id" : 1,
  "name" : "Mark"
}

Here we can see, without using @JsonAutoDetect, Jackson is unable to deserialize to private fields. Using @JsonAutoDetect we can include private fields which are not accessible during deserialization otherwise.

Jackson Annotations - @JsonTypeInfo

Overview

@JsonTypeInfo annotation is used to indicate details of type information which is to be included in serialization and de-serialization.

Consider a case, where subclasses extends a base class and deserialization is done using base class.

class Shape {
   public String name;    
   Shape(String name){
      this.name = name;
   }
}
class Square extends Shape {
   public double length;
   Square(){
      this(null,0.0);
   }
   Square(String name, double length){
      super(name);
      this.length = length;
   }
}
class Circle extends Shape {
   public double radius;  
   Circle(){
      this(null,0.0);
   }
   Circle(String name, double radius) {
      super(name);
      this.radius = radius;
   }
}
...
String json = "{\"name\":\"CustomCircle\",\"radius\":1.0, \"type\":\"circle\"}";
Circle circle = new ObjectMapper().readerFor(Shape.class).readValue(json);

Now in order to achieve this functionality, we can use @JsonTypeName on the classes to define their type and @JsonTypeInfo to map the correct class during serialization −

@JsonTypeName("square")
static class Square extends Shape { ... }

@JsonTypeName("circle")
static class Circle extends Shape { ... }

...

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, 
   include = As.PROPERTY, property = "type") @JsonSubTypes({
      
   @JsonSubTypes.Type(value = Square.class, name = "square"),
   @JsonSubTypes.Type(value = Circle.class, name = "circle")
})

Example - Deserialization using @JsonTypeInfo

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]) throws IOException {
      Shape shape = new JacksonTester.Circle("CustomCircle", 1);
      String result = new ObjectMapper()
         .writerWithDefaultPrettyPrinter()
         .writeValueAsString(shape);
      System.out.println(result);   
      String json = "{\"name\":\"CustomCircle\",\"radius\":1.0, \"type\":\"circle\"}";
      Circle circle = new ObjectMapper().readerFor(Shape.class).readValue(json);
      System.out.println(circle.name);
   }
   @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, 
      include = As.PROPERTY, property = "type") @JsonSubTypes({
      
      @JsonSubTypes.Type(value = Square.class, name = "square"),
      @JsonSubTypes.Type(value = Circle.class, name = "circle")
   })
   static class Shape {
      public String name;    
      Shape(String name){
         this.name = name;
      }
   }
   @JsonTypeName("square")
   static class Square extends Shape {
      public double length;
      Square(){
         this(null,0.0);
      }
      Square(String name, double length){
         super(name);
         this.length = length;
      }
   }
   @JsonTypeName("circle")
   static class Circle extends Shape {
      public double radius;  
      Circle(){
         this(null,0.0);
      }
      Circle(String name, double radius) {
         super(name);
         this.radius = radius;
      }
   }
}

Output

Run the JacksonTester and verify the output −

{
   "type" : "circle",
   "name" : "CustomCircle",
   "radius" : 1.0
}
CustomCircle

Jackson Annotations - @JsonSubTypes

Overview

@JsonSubTypes annotation is used to indicate subtypes of types annotated.

Consider a case, where subclasses extends a base class and deserialization is done using base class.

class Shape {
   public String name;    
   Shape(String name){
      this.name = name;
   }
}
class Square extends Shape {
   public double length;
   Square(){
      this(null,0.0);
   }
   Square(String name, double length){
      super(name);
      this.length = length;
   }
}
class Circle extends Shape {
   public double radius;  
   Circle(){
      this(null,0.0);
   }
   Circle(String name, double radius) {
      super(name);
      this.radius = radius;
   }
}
...
String json = "{\"name\":\"CustomCircle\",\"radius\":1.0, \"type\":\"circle\"}";
Circle circle = new ObjectMapper().readerFor(Shape.class).readValue(json);

Now in order to achieve this functionality, we can use @JsonTypeName on the classes to define their type and @JsonTypeInfo to map the correct class during serialization. In @JsonTypeInfo, we're setting subtypes using @JsonSubTypes

@JsonTypeName("square")
static class Square extends Shape { ... }

@JsonTypeName("circle")
static class Circle extends Shape { ... }

...

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, 
   include = As.PROPERTY, property = "type") @JsonSubTypes({
      
   @JsonSubTypes.Type(value = Square.class, name = "square"),
   @JsonSubTypes.Type(value = Circle.class, name = "circle")
})

Example - Deserialization using @JsonSubTypes

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]) throws IOException {
      Shape shape = new JacksonTester.Circle("CustomCircle", 1);
      String result = new ObjectMapper()
         .writerWithDefaultPrettyPrinter()
         .writeValueAsString(shape);
      System.out.println(result);   
      String json = "{\"name\":\"CustomCircle\",\"radius\":1.0, \"type\":\"circle\"}";
      Circle circle = new ObjectMapper().readerFor(Shape.class).readValue(json);
      System.out.println(circle.name);
   }
   @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, 
      include = As.PROPERTY, property = "type") @JsonSubTypes({
      
      @JsonSubTypes.Type(value = Square.class, name = "square"),
      @JsonSubTypes.Type(value = Circle.class, name = "circle")
   })
   static class Shape {
      public String name;    
      Shape(String name){
         this.name = name;
      }
   }
   @JsonTypeName("square")
   static class Square extends Shape {
      public double length;
      Square(){
         this(null,0.0);
      }
      Square(String name, double length){
         super(name);
         this.length = length;
      }
   }
   @JsonTypeName("circle")
   static class Circle extends Shape {
      public double radius;  
      Circle(){
         this(null,0.0);
      }
      Circle(String name, double radius) {
         super(name);
         this.radius = radius;
      }
   }
}

Output

Run the JacksonTester and verify the output −

{
   "type" : "circle",
   "name" : "CustomCircle",
   "radius" : 1.0
}
CustomCircle

Jackson Annotations - @JsonTypeName

Overview

@JsonTypeName annotation is used to set type names to be used for annotated class.

Consider a case, where subclasses extends a base class and deserialization is done using base class.

class Shape {
   public String name;    
   Shape(String name){
      this.name = name;
   }
}
class Square extends Shape {
   public double length;
   Square(){
      this(null,0.0);
   }
   Square(String name, double length){
      super(name);
      this.length = length;
   }
}
class Circle extends Shape {
   public double radius;  
   Circle(){
      this(null,0.0);
   }
   Circle(String name, double radius) {
      super(name);
      this.radius = radius;
   }
}
...
String json = "{\"name\":\"CustomCircle\",\"radius\":1.0, \"type\":\"circle\"}";
Circle circle = new ObjectMapper().readerFor(Shape.class).readValue(json);

Now in order to achieve this functionality, we can use @JsonTypeName on the classes to define their type and @JsonTypeInfo to map the correct class during serialization. In @JsonTypeInfo, we're setting subtypes using @JsonSubTypes

@JsonTypeName("square")
static class Square extends Shape { ... }

@JsonTypeName("circle")
static class Circle extends Shape { ... }

...

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, 
   include = As.PROPERTY, property = "type") @JsonSubTypes({
      
   @JsonSubTypes.Type(value = Square.class, name = "square"),
   @JsonSubTypes.Type(value = Circle.class, name = "circle")
})

Example - Deserialization using @JsonTypeName

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]) throws IOException {
      Shape shape = new JacksonTester.Circle("CustomCircle", 1);
      String result = new ObjectMapper()
         .writerWithDefaultPrettyPrinter()
         .writeValueAsString(shape);
      System.out.println(result);   
      String json = "{\"name\":\"CustomCircle\",\"radius\":1.0, \"type\":\"circle\"}";
      Circle circle = new ObjectMapper().readerFor(Shape.class).readValue(json);
      System.out.println(circle.name);
   }
   @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, 
      include = As.PROPERTY, property = "type") @JsonSubTypes({
      
      @JsonSubTypes.Type(value = Square.class, name = "square"),
      @JsonSubTypes.Type(value = Circle.class, name = "circle")
   })
   static class Shape {
      public String name;    
      Shape(String name){
         this.name = name;
      }
   }
   @JsonTypeName("square")
   static class Square extends Shape {
      public double length;
      Square(){
         this(null,0.0);
      }
      Square(String name, double length){
         super(name);
         this.length = length;
      }
   }
   @JsonTypeName("circle")
   static class Circle extends Shape {
      public double radius;  
      Circle(){
         this(null,0.0);
      }
      Circle(String name, double radius) {
         super(name);
         this.radius = radius;
      }
   }
}

Output

Run the JacksonTester and verify the output −

{
   "type" : "circle",
   "name" : "CustomCircle",
   "radius" : 1.0
}
CustomCircle

Jackson Annotations - @JsonProperty

Overview

@JsonProperty annotation is used at mark a property of special type to be ignored.

Example - Deserialization without using @JsonProperty

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]) throws IOException {
      ObjectMapper mapper = new ObjectMapper();
      String json = "{\"id\" : 1}";
      Student student = mapper.readerFor(Student.class).readValue(json);
      System.out.println(student.getTheId());
   }
}
class Student {
   private int id;
   Student(){}
   Student(int id){
      this.id = id;
   }
   public int getTheId() {
      return id;
   }
   public void setTheId(int id) {
      this.id = id;
   }   
}

Output

Run the JacksonTester and verify the output −

1

Example - Deserialization with @JsonProperty

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]) throws IOException {
      ObjectMapper mapper = new ObjectMapper();
      String json = "{\"id\" : 1}";
      Student student = mapper.readerFor(Student.class).readValue(json);
      System.out.println(student.getTheId());
   }
}
class Student {
   private int id;
   Student(){}
   Student(int id){
      this.id = id;
   }
   @JsonProperty("id")
   public int getTheId() {
      return id;
   }
   @JsonProperty("id")
   public void setTheId(int id) {
      this.id = id;
   }   
}

Output

Run the JacksonTester and verify the output −

1

Here we can see, even without using @JsonProperty, Jackson is deserializing using the available setter method. Use of @JsonProperty is recommended where we've custom setter methods instead of standard setter methods.

Jackson Annotations - @JsonFormat

Overview

@JsonFormat annotation is used to specify format while serialization or de-serialization. It is mostly used with Date fields.

Example - Serialization without using @JsonFormat

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]) throws IOException, ParseException {
      ObjectMapper mapper = new ObjectMapper();
      SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MM-yyyy");
      Date date = simpleDateFormat.parse("20-12-1984");

      Student student = new Student(1, date);
      String jsonString = mapper
         .writerWithDefaultPrettyPrinter()
         .writeValueAsString(student);
      System.out.println(jsonString);
   }
}
class Student { 
   public int id;
   public Date birthDate;
   Student(int id, Date birthDate){
      this.id = id;
      this.birthDate = birthDate;
   } 
}

Output

Run the JacksonTester and verify the output −

{
  "id" : 1,
  "birthDate" : 472329000000
}

Example - Serialization with @JsonFormat

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]) throws IOException, ParseException {
      ObjectMapper mapper = new ObjectMapper();
      SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MM-yyyy");
      Date date = simpleDateFormat.parse("20-12-1984");

      Student student = new Student(1, date);
      String jsonString = mapper
         .writerWithDefaultPrettyPrinter()
         .writeValueAsString(student);
      System.out.println(jsonString);
   }
}
class Student { 
   public int id;
   @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy")
   public Date birthDate;
   Student(int id, Date birthDate){
      this.id = id;
      this.birthDate = birthDate;
   } 
}

Output

Run the JacksonTester and verify the output −

{
  "id" : 1,
  "birthDate" : "19-12-1984"
}

Here we can see, without using @JsonFormat, Jackson is serializing the date to timestamp whereas using @JsonFormat annotation, we're specifying the format in which date is to be serialized.

Jackson Annotations - @JsonUnwrapped

Overview

@JsonUnwrapped annotation is used to unwrap values of objects during serialization or de-serialization.

Example - Serialization without using @JsonUnwrapped

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]) throws IOException, ParseException{
      ObjectMapper mapper = new ObjectMapper();
      SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MM-yyyy");
      Date date = simpleDateFormat.parse("20-12-1984");
      Student.Name name = new Student.Name();
      name.first = "Jane";
      name.last = "Doe";
      Student student = new Student(1, name);
      String jsonString = mapper
         .writerWithDefaultPrettyPrinter()
         .writeValueAsString(student);
      System.out.println(jsonString);
   }
}
class Student {
   public int id;   
   public Name name;
   Student(int id, Name name){
      this.id = id;
      this.name = name;
   }
   static class Name {
      public String first;
      public String last;
   }
}

Output

Run the JacksonTester and verify the output −

{
  "id" : 1,
  "name" : {
    "first" : "Jane",
    "last" : "Doe"
  }
}

Example - Serialization with @JsonUnwrapped

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import com.fasterxml.jackson.annotation.JsonUnwrapped;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]) throws IOException, ParseException{
      ObjectMapper mapper = new ObjectMapper();
      SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MM-yyyy");
      Date date = simpleDateFormat.parse("20-12-1984");
      Student.Name name = new Student.Name();
      name.first = "Jane";
      name.last = "Doe";
      Student student = new Student(1, name);
      String jsonString = mapper
         .writerWithDefaultPrettyPrinter()
         .writeValueAsString(student);
      System.out.println(jsonString);
   }
}
class Student {
   public int id;   
   @JsonUnwrapped
   public Name name;
   Student(int id, Name name){
      this.id = id;
      this.name = name;
   }
   static class Name {
      public String first;
      public String last;
   }
}

Output

Run the JacksonTester and verify the output −

{
  "id" : 1,
  "first" : "Jane",
  "last" : "Doe"
}

Here we can see, without using @JsonUnwrapped, Jackson is serializing the name object to a new JSON object whereas using @JsonUnwrapped annotation, we're able to unwrap name field and serialize them as other fields.

Jackson Annotations - @JsonView

Overview

@JsonView annotation is used to control values to be serialized or not.

How to use @JsonView

Define Views

class Views {
   static class Public {}
   static class Internal extends Public {}
}

Annotate Properties with @JsonView

Here we've defined two scopes as Public and Internal. Now we'll control our serialization of values using @JsonView annotation.

class Student {
   @JsonView(Views.Public.class)
   public int id;
   @JsonView(Views.Public.class)
   public String name;
   @JsonView(Views.Internal.class)
   public int age;
   ...
}

Serialize using required View defined above.

Now, during serialization, we can define using View, here Views.Public as which properties are to be serialized.

String jsonString = mapper
         .writerWithDefaultPrettyPrinter()
         .withView(Views.Public.class)
         .writeValueAsString(student);

Example - Serialization with @JsonView

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import java.text.ParseException;
import com.fasterxml.jackson.annotation.JsonView;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]) throws IOException, ParseException {
      ObjectMapper mapper = new ObjectMapper();     
      Student student = new Student(1, "Mark", 12);
      String jsonString = mapper
         .writerWithDefaultPrettyPrinter()
         .withView(Views.Public.class)
         .writeValueAsString(student);
      System.out.println(jsonString);
   }
}
class Student {
   @JsonView(Views.Public.class)
   public int id;
   @JsonView(Views.Public.class)
   public String name;
   @JsonView(Views.Internal.class)
   public int age;

   Student(int id, String name, int age) {
      this.id = id;
      this.name = name;
      this.age = age;
   }
}
class Views {
   static class Public {}
   static class Internal extends Public {}
}

Output

Run the JacksonTester and verify the output −

{
  "id" : 1,
  "name" : "Mark"
}

Here we can see, using @JsonView annotation, we're able to control serialization of properties.

Jackson Annotations - @JsonManagedReference

Overview

@JsonManagedReferences and @JsonBackReferences are used to display objects with parent child relationship. @JsonManagedReferences is used to refer to parent object and @JsonBackReferences is used to mark child objects.

Creating Parent-Child Relationship

Annotate Parent

Here we're defining Student object as owner of the book and annotating with @JsonManagedReference.

class Book {
   public int id;
   public String name;
   ...
   @JsonManagedReference
   public Student owner;
}

Annotate Child

Here we're defining List<Book> object as child of the student and annotating it using @JsonBackReference.

class Student {
   public int rollNo;
   public String name;

   @JsonBackReference
   public List<Book> books;
   ...
}

Example - Serialization with @JsonManagedReference

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]) throws IOException, ParseException {
      ObjectMapper mapper = new ObjectMapper();     
      Student student = new Student(1, "Mark");
      Book book1 = new Book(1,"Learn HTML", student);
      Book book2 = new Book(1,"Learn JAVA", student);

      student.addBook(book1);
      student.addBook(book2);

      String jsonString = mapper 
         .writerWithDefaultPrettyPrinter()
         .writeValueAsString(book1);
      System.out.println(jsonString);
   }
}
class Student {
   public int rollNo;
   public String name;

   @JsonBackReference
   public List<Book> books;

   Student(int rollNo, String name){
      this.rollNo = rollNo;
      this.name = name;
      this.books = new ArrayList<Book>();
   }
   public void addBook(Book book){
      books.add(book);
   }
}
class Book {
   public int id;
   public String name;

   Book(int id, String name, Student owner){
      this.id = id;
      this.name = name;
      this.owner = owner;
   }
   @JsonManagedReference
   public Student owner;
}

Output

Run the JacksonTester and verify the output −

{
  "id" : 1,
  "name" : "Learn HTML",
  "owner" : {
    "rollNo" : 1,
    "name" : "Mark"
  }
}

Here we can see, using @JsonManagedReference and @JsonBackReferences annotations, we're able to define parent-child relationship.

Jackson Annotations - @JsonBackReferences

Overview

@JsonManagedReferences and @JsonBackReferences are used to display objects with parent child relationship. @JsonManagedReferences is used to refer to parent object and @JsonBackReferences is used to mark child objects.

Creating Parent-Child Relationship

Annotate Parent

Here we're defining Student object as owner of the book and annotating with @JsonManagedReference.

class Book {
   public int id;
   public String name;
   ...
   @JsonManagedReference
   public Student owner;
}

Annotate Child

Here we're defining List<Book> object as child of the student and annotating it using @JsonBackReference.

class Student {
   public int rollNo;
   public String name;

   @JsonBackReference
   public List<Book> books;
   ...
}

Example - Serialization with @JsonBackReferences

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]) throws IOException, ParseException {
      ObjectMapper mapper = new ObjectMapper();     
      Student student = new Student(1, "Mark");
      Book book1 = new Book(1,"Learn HTML", student);
      Book book2 = new Book(1,"Learn JAVA", student);

      student.addBook(book1);
      student.addBook(book2);

      String jsonString = mapper 
         .writerWithDefaultPrettyPrinter()
         .writeValueAsString(book1);
      System.out.println(jsonString);
   }
}
class Student {
   public int rollNo;
   public String name;

   @JsonBackReference
   public List<Book> books;

   Student(int rollNo, String name){
      this.rollNo = rollNo;
      this.name = name;
      this.books = new ArrayList<Book>();
   }
   public void addBook(Book book){
      books.add(book);
   }
}
class Book {
   public int id;
   public String name;

   Book(int id, String name, Student owner){
      this.id = id;
      this.name = name;
      this.owner = owner;
   }
   @JsonManagedReference
   public Student owner;
}

Output

Run the JacksonTester and verify the output −

{
  "id" : 1,
  "name" : "Learn HTML",
  "owner" : {
    "rollNo" : 1,
    "name" : "Mark"
  }
}

Here we can see, using JsonManagedReference and @JsonBackReferences annotations, we're able to define parent-child relationship.

Jackson Annotations - @JsonIdentityInfo

Overview

@JsonIdentityInfo is used when objects have parent child relationship. @JsonIdentityInfo is used to indicate that object identity will be used during serialization/de-serialization.

Creating Identity Info

Annotate Parent Class

Here we're defining Student object as owner of the book and annotating with @JsonIdentityInfo.

@JsonIdentityInfo(
   generator = ObjectIdGenerators.PropertyGenerator.class,
   property = "id")
class Student { 
...
}

Annotate Child Class

Here we're defining Book as child object and annotating with @JsonIdentityInfo.

@JsonIdentityInfo(
   generator = ObjectIdGenerators.PropertyGenerator.class,
   property = "id")
class Book{
...
}

Example - Serialization with @JsonIdentityInfo

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]) throws IOException, ParseException{
      ObjectMapper mapper = new ObjectMapper();     
      Student student = new Student(1,13, "Mark");
      Book book1 = new Book(1,"Learn HTML", student);
      Book book2 = new Book(2,"Learn JAVA", student);

      student.addBook(book1);
      student.addBook(book2);

      String jsonString = mapper
         .writerWithDefaultPrettyPrinter()
         .writeValueAsString(book1);
      System.out.println(jsonString);
   }
}
@JsonIdentityInfo(
   generator = ObjectIdGenerators.PropertyGenerator.class,
   property = "id")
class Student { 
   public int id;
   public int rollNo;
   public String name;
   public List<Book> books;
   
   Student(int id, int rollNo, String name){
      this.id = id;
      this.rollNo = rollNo;
      this.name = name;
      this.books = new ArrayList<Book>();
   }
   public void addBook(Book book){
      books.add(book);
   }
}
@JsonIdentityInfo(
   generator = ObjectIdGenerators.PropertyGenerator.class,
   property = "id")
class Book{
   public int id;
   public String name;

   Book(int id, String name, Student owner){
      this.id = id;
      this.name = name;
      this.owner = owner;
   }
   public Student owner;
}

Output

Run the JacksonTester and verify the output −

{
  "id" : 1,
  "name" : "Learn HTML",
  "owner" : {
    "id" : 1,
    "rollNo" : 13,
    "name" : "Mark",
    "books" : [ 1, {
      "id" : 2,
      "name" : "Learn JAVA",
      "owner" : 1
    } ]
  }
}

Here we can see, using JsonIdentityInfo to indicate object identify.

Jackson Annotations - @JsonFilter

Overview

@JsonIdentityInfo is used to apply filter during serialization/de-serialization like which properties are to be used or not.

Usage of @JsonFilter

Annotate Class with @JsonFilter

@JsonFilter("nameFilter")
class Student {
   public int id;
   ...
}

Create a Filter

FilterProvider filters = new SimpleFilterProvider() .addFilter(
   "nameFilter", SimpleBeanPropertyFilter.filterOutAllExcept("name"));

Apply the Filter

String jsonString = mapper.writer(filters)             
   .withDefaultPrettyPrinter()
   .writeValueAsString(student);

Example - Serialization with @JsonFilter

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import java.text.ParseException;

import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;

public class JacksonTester {
   public static void main(String args[]) throws IOException, ParseException {
      ObjectMapper mapper = new ObjectMapper();     
      Student student = new Student(1,13, "Mark");
      
      FilterProvider filters = new SimpleFilterProvider() .addFilter(
         "nameFilter", SimpleBeanPropertyFilter.filterOutAllExcept("name"));
      
      String jsonString = mapper.writer(filters)             
         .withDefaultPrettyPrinter()
         .writeValueAsString(student);
      System.out.println(jsonString);
   }
}
@JsonFilter("nameFilter")
class Student {
   public int id;
   public int rollNo;
   public String name;

   Student(int id, int rollNo, String name) {
      this.id = id;
      this.rollNo = rollNo;
      this.name = name;
   }   
}

Output

Run the JacksonTester and verify the output −

{
  "name" : "Mark"
}

Here we can see, using JsonFilter we're able to filter object properties.

Jackson Annotations - Custom Annotation

Overview

We can create custom annotation easily using @JacksonAnnotationsInside annotation.

Create a Custom Annotation

Create a Custom annotation which maintains property order and excludes null values during serialization.

@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonInclude(value = Include.NON_NULL)
@JsonPropertyOrder({ "rollNo", "id", "name" })
@interface CustomAnnotation {}

Apply the Custom Annotation

@CustomAnnotation
class Student {
...
}

Example - Serialization with Custom Annotation

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.text.ParseException;

import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]) throws IOException, ParseException {
      ObjectMapper mapper = new ObjectMapper();     
      Student student = new Student(1,13, "Mark");

      String jsonString = mapper  
         .writerWithDefaultPrettyPrinter()
         .writeValueAsString(student);
      System.out.println(jsonString);
   }
}

@CustomAnnotation
class Student {
   public int id;
   public int rollNo;
   public String name;
   public String otherDetails;

   Student(int id, int rollNo, String name){
      this.id = id;
      this.rollNo = rollNo;
      this.name = name;
   }   
}

@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonInclude(value = Include.NON_NULL)
@JsonPropertyOrder({ "rollNo", "id", "name" })
@interface CustomAnnotation {}

Output

Run the JacksonTester and verify the output −

{
  "rollNo" : 13,
  "id" : 1,
  "name" : "Mark"
}

Here we can see, using @JacksonAnnotationsInside to create a custom annotation and applied the same.

Jackson Annotations - Mixin Annotation

Overview

Mixin Annotation is a way to associate annotations without modifying the target class.

Create a class to be used as Mixin

Create a class where required annotation is applied.

@JsonIgnoreType
class MixInForIgnoreType {}

Create a class where annotation is to be applied indirectly.

class Name {
   public String name;
   Name(String name){
      this.name = name;
   }       
}

Apply the Mixin

ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(Name.class, MixInForIgnoreType.class);

Example - Serialization without Mixin Annotation

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;

import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]) {
      try {
	     ObjectMapper mapper = new ObjectMapper();
         Student student = new Student(1,11,"1ab","Mark");       
         String jsonString = mapper
            .writerWithDefaultPrettyPrinter()
            .writeValueAsString(student);
         System.out.println(jsonString);
      }
      catch (IOException e) { 
         e.printStackTrace();
      }     
   }
}
class Student {
   public int id;
   public String systemId;
   public int rollNo;
   public Name nameObj;

   Student(int id, int rollNo, String systemId, String name) {
      this.id = id;
      this.systemId = systemId;
      this.rollNo = rollNo;
      nameObj = new Name(name);
   }
}
class Name {
   public String name;
   Name(String name){
      this.name = name;
   }       
}

Output

Run the JacksonTester and verify the output −

{
  "id" : 1,
  "systemId" : "1ab",
  "rollNo" : 11,
  "nameObj" : {
    "name" : "Mark"
  }
}

Example - Serialization with Mixin Annotation

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;

import com.fasterxml.jackson.annotation.JsonIgnoreType;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]) {
      try {
    	 Student student = new Student(1,11,"1ab","Mark"); 
         ObjectMapper mapper = new ObjectMapper();
         mapper.addMixIn(Name.class, MixInForIgnoreType.class);
         String jsonString = mapper
            .writerWithDefaultPrettyPrinter()
            .writeValueAsString(student);
         System.out.println(jsonString);
      }
      catch (IOException e) { 
         e.printStackTrace();
      }     
   }
}
class Student {
   public int id;
   public String systemId;
   public int rollNo;
   public Name nameObj;

   Student(int id, int rollNo, String systemId, String name) {
      this.id = id;
      this.systemId = systemId;
      this.rollNo = rollNo;
      nameObj = new Name(name);
   }
}
class Name {
   public String name;
   Name(String name){
      this.name = name;
   }       
}
@JsonIgnoreType
class MixInForIgnoreType {}

Output

Run the JacksonTester and verify the output −

{
  "id" : 1,
  "systemId" : "1ab",
  "rollNo" : 11
}

Here we can see, using addMixin() method, we're able to apply annotations without modify the original class.

Jackson Annotations - Disable Annotation

Overview

We can disable jackson annotations using disable() function of ObjectMapper.

Disable Jackson Annotations

Using ObjectMapper.disble() method, we can easily disable the Jackson Annotations.

 new ObjectMapper().disable(MapperFeature.USE_ANNOTATIONS);

Example - Serialization without disabling Annotation

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;

import com.fasterxml.jackson.annotation.JsonIgnoreType;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]){

      try{
	     ObjectMapper mapper = new ObjectMapper();
         Student student = new Student(1,11,"1ab","Mark");       
         String jsonString = mapper
            .writerWithDefaultPrettyPrinter()
            .writeValueAsString(student);
         System.out.println(jsonString);

      }
      catch (IOException e) { 
         e.printStackTrace();
      }     
   }
}
class Student {
   public int id;
   public String systemId;
   public int rollNo;
   public Name nameObj;

   Student(int id, int rollNo, String systemId, String name){
      this.id = id;
      this.systemId = systemId;
      this.rollNo = rollNo;
      nameObj = new Name(name);
   }
}
@JsonIgnoreType
class Name {
   public String name;
   Name(String name){
      this.name = name;
   }       
}

Output

Run the JacksonTester and verify the output −

{
  "id" : 1,
  "systemId" : "1ab",
  "rollNo" : 11
}

Example - Serialization with disabled Annotation

JacksonTester.java

package com.tutorialspoint;

import java.io.IOException;

import com.fasterxml.jackson.annotation.JsonIgnoreType;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTester {
   public static void main(String args[]){
      try{
         Student student = new Student(1,11,"1ab","Mark");       
        
         ObjectMapper mapper = new ObjectMapper();
         mapper.disable(MapperFeature.USE_ANNOTATIONS);
         String jsonString = mapper
            .writerWithDefaultPrettyPrinter()
            .writeValueAsString(student);
         System.out.println(jsonString);
      }
      catch (IOException e) { 
         e.printStackTrace();
      }     
   }
}
class Student {
   public int id;
   public String systemId;
   public int rollNo;
   public Name nameObj;

   Student(int id, int rollNo, String systemId, String name){
      this.id = id;
      this.systemId = systemId;
      this.rollNo = rollNo;
      nameObj = new Name(name);
   }
}
@JsonIgnoreType
class Name {
   public String name;
   Name(String name){
      this.name = name;
   }       
}

Output

Run the JacksonTester and verify the output −

{
  "id" : 1,
  "systemId" : "1ab",
  "rollNo" : 11,
  "nameObj" : {
    "name" : "Mark"
  }
}

Here we can see, using disable() method, we're able to disable jackson annotations to be processed.

Advertisements