Saturday, August 21, 2021

3 ways to ignore null fields while converting Java object to JSON using Jackson? Example

Ignoring null fields or attribute is a one of the common requirement while marshaling Java object to JSON string because Jackson just prints null when a reference filed is null, which you may not want. For example, if you have a Java object which has a String field whose value is null when you convert this object to Json, you will see null in front of that. In order to better control JSON output, you can ignore null fields, and Jackson provides a couple of options to do that. You can ignore null fields at the class level by using @JsonInclude(Include.NON_NULL) to only include non-null fields, thus excluding any attribute whose value is null.

You can also use the same annotation at the field level to instruct Jackson to ignore that field while converting Java object to json if it's null. You can also ignore nulls at the object mapper level, e.g. by configuring it to ignore nulls globally.

I'll show you the example of each of these three ways to ignore null fields using Jackson, but before that let's first see an example of marshaling Java objects with null fields using Jackson to understand the problem better.

Btw, I expect that you know Java and are familiar with using third-party libraries like Jackson in your code. If you happen to just start with Java or want to refresh your Java knowledge, I suggest you first go through these free online Java courses to learn Javascratch. It's also the most up-to-date course and covers new features from recent Java versions.





What happens when a field is null?

Suppose you have an object which has a String field to contain the author, Now if you create a book with the null author, and you want to convert that into JSON, what will happen? A NullPointerException or something else? let's see


public class JacksonTest {
 
  public static void main(String args[]) throws JsonProcessingException {
    // let's create a book with author as null
    Book cleanCode = new Book("Clean Code", null, 42);
 
    ObjectMapper mapper = new ObjectMapper();
    String json = mapper.writeValueAsString(cleanCode);
 
    System.out.println(json);
 
  }
}

This will print the following output:

{"title":"Clean Code","author":null,"price":42}

You can see that the author is printed as null, which may not be ideal for many. This is still better than a NullPointerException but you could have been even better if the author field was not included in the output altogether.

 And, if that's precisely what you want, then you can ignore the fields with null values using @JsonInclude annotation in Jackson. Btw, if you are new to Jackson library then you can also check out this Jackson Quick Start: JSON Serialization with Java Made Easy course on Udemy. It's completely free and a good place to start Jackson basics.

3 ways to ignore null fields while converting Java object to JSON using Jackson



Ignoring null fields at field level in Jackson

Now, let's first see how we can ignore the fields with null values in JSON output at the field level. We can do this by annotating each field with @JsonInclude(Include.NON_NULL) annotation. If a field is annotated by this, then it will be not included in the JSON output if its null.

Here is an example to confirm this:

public class Book implements Comparable<Book> {
  private String title;
 
  @JsonInclude(Include.NON_NULL)
  private String author;
 
  private int price;
 
  public Book(String title, String author, int price) {
    this.title = title;
    this.author = author;
    this.price = price;
  }
 
}

If you rerun the main method, this time it will produce a different output, I mean, without the author field as shown below:

{"title":"Clean Code","price":42}

But if you make the title null, then it will be the same issue as we have only ignored the author. So this solution makes sense to annotate all optional fields with @JsonInclude(Include.NON_NULL).

Btw, I am assuming here that you are familiar with JSON structure and JSON itself in general, If you are not, you can see this Introduction to JSON course on Udemy to understand the structure and properties of JSON.

best course to learn JSON for Programmers Udemy



Excluding null fields at class level

Jackson also allows you to ignore null fields at the class level, which means every field which has a null value will be ignored. This is the same as annotating all fields with @JsonInclude(Include.NON_NULL) annotation.

So if you have a requirement where all the fields are optional or may contain null then instead of annotating every single field it's better to do it once at the class level as shown below:

@JsonInclude(Include.NON_NULL)
public class Book implements Comparable<Book> {
  private String title;
  private String author;
  private int price;
 
  public Book(String title, String author, int price) {
    this.title = title;
    this.author = author;
    this.price = price;
  }
}


If you run the main class, we will again get the same JSON output as we got in the previous example, as shown below:

{"title":"Clean Code","price":42}

but if you make the title also null then you only get the price in the JSON output:

public class JacksonTest {
 
  public static void main(String args[]) throws JsonProcessingException {
 
    // let's create a book with author as null
    Book cleanCode = new Book(null, null, 42);
 
    ObjectMapper mapper = new ObjectMapper();
    String json = mapper.writeValueAsString(cleanCode);
 
    System.out.println(json);
  }
 
}
 

Output:
{"price":42}

This happens because the Book class is annotated with @JsonInclude(Include.NON_NULL) which will exclude any null field. In this case, both the title and author were ignored.

You can see Jackson is a very popular and efficient Java library to map Java objects to JSON and vice-versa. If you want to learn the basics of the Jackson library and how to use them, I suggest you take a look at the Java: JSON Databinding with Jackson course on Pluralsight. One of the best courses to learn Jackson API for Java developers.

best course to learn Jackson API for Java developers




Ignoring null fields Globally

You can also exclude null fields globally while converting Java objects to JSON by configuring this behavior on the ObjectMapper itself. This means all the classes will have this feature by themselves, and any field with null values will be ignored.

You can also configure ObjectMapper to ignore null fields globally by calling the setSerializationInclusion(Include.NON_NULL) method, as shown in the following example:

public class JacksonTest {
 
  public static void main(String args[]) throws JsonProcessingException {
 
    // let's create a book with author as null
    Book cleanCode = new Book(null, null, 42);
 
    ObjectMapper mapper = new ObjectMapper();
 
    // configure ObjectMapper to exclude null fields whiel serializing
    mapper.setSerializationInclusion(Include.NON_NULL);
 
    String json = mapper.writeValueAsString(cleanCode);
 
    System.out.println(json);
  }
 
}

Output
{"price":42}

This time also you get the same output even though you don't have @JsonInclude(Include.NON_NULL) at the top of your Book class because ObjectMapper will automatically ignore any field with a null value when this option is set.

That's all about how to ignore null fields while converting Java objects to JSON strings using Jackson. You have 3 ways to do it, ignore fields with null value at the field level, or class level, or globally at the ObjectMapper level. The rule of thumb is that you do it at field level for greater control and start with annotating the optional field which can be null.


Other JSON tutorials and courses you may like:
  • How to parse JSON using Gson? (tutorial)
  • 5 JSON parsing libraries Java Developers Should Know (libraries)
  • 10 Online courses to learn JavaScript in depth (courses)
  • How to parse a JSON array in Java? (tutorial)
  • Top 5 Courses to become full-stack Java developer (courses)
  • How to solve UnrecognizedPropertyException in Jackson? (solution)
  • 10 Advanced Core Java Courses for Experienced Developers (courses)
  • How to convert JSON to HashMap in Java? (guide)
  • 10 Things Java developers should learn?  (article)
  • How to ignore unknown properties while parsing JSON in Java? (tutorial)
  • Top 5 Websites to learn Java For FREE (websites)
  • How to parse JSON with date fields in Java? (example)
  • 5 Courses to learn RESTful  API and Web services in Java? (courses)
  • 10 free courses to learn Java in-depth (resource)

Thanks for reading this article so far. If you like the Jackson JSON tutorial, then please share it with your friends and colleagues. If you have any questions or feedback, then please drop a note.

P. S. - If are a complete beginner about JSON (JavaScript Object Notation) I strongly suggest you go through the Introduction to JSON course on Udemy to understand the structure and properties of JSON. This will help you a lot while dealing with JSON output, formating them, and producing them from your own API.

13 comments:

  1. you need to add this at the beginning:
    import com.fasterxml.jackson.annotation.JsonInclude;

    And also please note you will get an error if you just write:
    @JsonInclude(Include.NON_NULL)

    Instead use:
    @JsonInclude(JsonInclude.Include.NON_NULL)

    ReplyDelete
    Replies
    1. diff beween @JsonInclude(Include.NON_NULL) and @JsonInclude(JsonInclude.Include.NON_NULL)

      Delete
  2. if we are using same object for 2 endpoints - i want to not include certain fields in 1 endpoint, do not send these certain fields in another endpoint

    ReplyDelete
    Replies
    1. You can do this by using two separate Object Mapper for these end points.

      Delete
  3. Replies
    1. Thank you Mithilesh, glad you liked this tutorial

      Delete
  4. Can I ignore null field, when I am using that objects.

    ReplyDelete
    Replies
    1. If you don't need those fields then yes better ignore them. Though, if you need then just read and assign, it could be null or non-null

      Delete
  5. How do I ignore price in above example ,because price is int data type with default value as zero?

    ReplyDelete
    Replies
    1. You can try same method, when you convert your object to JSON String then you will not see the price in generated String. Let me know if you face any issue or error

      Delete
  6. Will this work if I use it on a view?

    public interface PersonView{
    String getFullName();
    Long getAge();

    @JsonInclude(JsonInclude.Include.NON_NULL)
    Double getSalary();
    }

    ReplyDelete

Feel free to comment, ask questions if you have any doubt.