Close

Jackson JSON - Using content attribute of @JsonInclude to apply include rules for Map entries and content of referential type

[Updated: Jul 13, 2018, Created: Jul 13, 2018]

@JsonInclude#content attribute can be used to to apply inclusion rules for the 'content' values of the target field. It works for only java.util.Map and referential types (like AtomicReference).

In case of Map, the entries are excluded if the corresponding values (not keys) do not satisfy the specified inclusion rule (these rules are nothing but one of the JsonInclude.Include values).

In case of a referential type e.g. AtomicReference, the value returned by AtomicReference#get() must satisfy the specified rule for inclusion.

This feature is not currently (as of Jackson 2.9.x) supported for arrays or Collections, but that support may be added in future versions.

Example

Java Object

package com.logicbig.example;

import com.fasterxml.jackson.annotation.JsonInclude;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

public class Employee {
  private String name;
  @JsonInclude(value = JsonInclude.Include.NON_EMPTY, content = JsonInclude.Include.NON_EMPTY)
  private AtomicReference<String> address;
  @JsonInclude(content = JsonInclude.Include.NON_DEFAULT)
  private Map<String, Integer> phones;
    .............
}

Above settings specify that if 'address' content is not empty per NON_EMPTY rule (i.e. AtomicReference.get() returns a non empty value) then it should be included in serialized JSON, otherwise it should be excluded. Also if 'address' itself is empty then it should be excluded (because of our specified 'value' attribute).

Also in case 'phones' field, if the Map's entry value (not key) is default (default value of integer is 0) then it should be excluded (check out NON_DEFAULT rule tutorial). We did not specify 'value' attribute in that case that means we don't want to exclude the Map property itself based on any rule, so if Map is itself empty or null it will be included in the serialized JSON.

Main class

public class ExampleMain {
  public static void main(String[] args) throws IOException {
      Employee employee = new Employee();
      employee.setName("Trish");
      employee.setAddress(new AtomicReference<>(""));
      employee.setPhones(Map.of("cell", 1112223, "work", 0));

      ObjectMapper om = new ObjectMapper();
      String jsonString = om.writeValueAsString(employee);
      System.out.println(jsonString);
  }
}
{"name":"Trish","phones":{"cell":1112223}}

Without 'content' attribute

Let's don't use content attribute in above example i.e.

public class Employee {
  private String name;
  @JsonInclude(value = JsonInclude.Include.NON_EMPTY)
  private AtomicReference<String> address;
  private Map<String, Integer> phones;
    .............
}

output in this case is:

{"name":"Trish","address":"","phones":{"cell":1112223,"work":0}}

'address' property is there because it is not empty per NON_EMPTY 'value' rule (has to be null content or null itself).

Now let's use only content attribute on 'address':

public class Employee {
  private String name;
  @JsonInclude(content = JsonInclude.Include.NON_EMPTY)
  private AtomicReference<String> address;
  private Map<String, Integer> phones;
    .............
}
{"name":"Trish","address":"","phones":{"cell":1112223,"work":0}}

'address' is still there but in this case because 'address' itself is not NON_EMPTY, not because of its content.

In simple words 'content' rules are only applied to the individual elements/content, it is not applied to the field/property itself.

Example Project

Dependencies and Technologies Used:

  • jackson-databind 2.9.6: General data-binding functionality for Jackson: works on core streaming API.
  • JDK 10
  • Maven 3.5.4

@JsonInclude#content example Select All Download
  • jackson-json-include-content-rules
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • Employee.java

    See Also