Close

Jackson JSON - Using @JsonFormat to serialize Collection And Number As JSON Objects

[Updated: Aug 8, 2018, Created: Aug 7, 2018]

@JsonFormat can also be used to serialize subclasses of java.util.Collection and java.lang.Number as POJOs instead of collection elements and Number scalar value respectively. It only works if the annotation is used on class level with @JsonFormat#shape=JsonFormat.Shape.OBJECT.

Example

Java Objects

For simplicity we are wrapping ArrayList in a subclass of AbstractList:

@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public class ArrayListEx<T> extends AbstractList<T> {
  private List<T> wrapperList = new ArrayList<>();
    .............
}

Following is an example subclass of Number:

@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public class BigIntegerEx extends BigInteger {
    .............
}

Using above classes in our main Java object:

public class Employee {
  private String name;
  private String dept;
  private ArrayListEx<String> phoneNumbers;
  private BigIntegerEx salary;
    .............
}

Main class

public class ExampleMain {
  public static void main(String[] args) throws IOException {
      Employee employee = new Employee();
      employee.setName("Amy");
      employee.setDept("Admin");
      ArrayListEx<String> list = new ArrayListEx<>();
      list.add("111-111-111");
      list.add("222-222-222");
      employee.setPhoneNumbers(list);
      employee.setSalary(new BigIntegerEx("4000"));

      System.out.println("-- before serialization --");
      System.out.println(employee);

      System.out.println("-- after serialization --");
      ObjectMapper om = new ObjectMapper();
      String jsonString = om.writeValueAsString(employee);
      System.out.println(jsonString);
  }
}
-- before serialization --
Employee{name='Amy', dept='Admin', phoneNumbers=[111-111-111, 222-222-222], salary=4000}
-- after serialization --
{"name":"Amy","dept":"Admin","phoneNumbers":{"wrapperList":["111-111-111","222-222-222"]},"salary":{"lowestSetBit":5}}

Without @JsonFormat

Let's remove @JsonFormat from both of our subclasses ArrayListEx and BigIntegerEx, in that case output will be

Employee{name='Amy', dept='Admin', phoneNumbers=[111-111-111, 222-222-222], salary=4000}
-- after serialization --
{"name":"Amy","dept":"Admin","phoneNumbers":["111-111-111","222-222-222"],"salary":4000}

By default Number is serialized as scalar (primitive) value. Also in case of Collection subclass, deserialization is also possible when @JsonFormat#shape=JsonFormat.Shape.OBJECTis used.

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

Serializing Collections/Numbers as object example Select All Download
  • jackson-json-format-collection-and-number
    • src
      • main
        • java
          • com
            • logicbig
              • example

See Also