Jackson provides SerializationFeature/DeserializationFeature (also known as Jackson configurations) to customize ObjectMapper
behavior. Followings are quick examples to get familiar with the commonly used such features.
Enabling Indented Output
A POJO:
public class MyObject {
private int intVal;
private String stringVal;
private List<String> list;
.............
}
Using default:
By default JSON output is not indented:
MyObject myObject = new MyObject(3, "test String",
List.of("one", "two"));
ObjectMapper om = new ObjectMapper();
String s = om.writeValueAsString(myObject);
System.out.println(s);
{"intVal":3,"stringVal":"test String","list":["one","two"]}
Enabling INDENT_OUTPUT
MyObject myObject = new MyObject(3, "test String",
List.of("one", "two"));
ObjectMapper om = new ObjectMapper();
om.enable(SerializationFeature.INDENT_OUTPUT);
String s = om.writeValueAsString(myObject);
System.out.println(s);
{
"intVal" : 3,
"stringVal" : "test String",
"list" : [ "one", "two" ]
}
Fail on Unknown Properties
Following POJO does not have a corresponding property for getStrVal() method (according to the Java Bean convention):
public class MyObject2 {
private int intVal;
public MyObject2(int intVal) {
this.intVal = intVal;
}
public MyObject2() {
}
public int getIntVal() {
return intVal;
}
public void setIntVal(int intVal) {
this.intVal = intVal;
}
public String getStrVal() {
return Integer.toString(intVal);
}
.............
}
Using default:
MyObject2 myObject = new MyObject2(3);
ObjectMapper om = new ObjectMapper();
String s = om.writeValueAsString(myObject);
System.out.println(s);
myObject = om.readValue(s, MyObject2.class);
System.out.println(myObject);
{"intVal":3,"strVal":"3"}
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "strVal" (class com.logicbig.example.MyObject2), not marked as ignorable (one known property: "intVal"])
at [Source: (String)"{"intVal":3,"strVal":"3"}"; line: 1, column: 23] (through reference chain: com.logicbig.example.MyObject2["strVal"])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:60)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:822)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1152)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1567)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1545)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:293)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4001)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2992)
at com.logicbig.example.DisableFailOnUnknownProps.defaultOutput(DisableFailOnUnknownProps.java:18)
Disabling FAIL_ON_UNKNOWN_PROPERTIES
MyObject2 myObject = new MyObject2(3);
ObjectMapper om = new ObjectMapper();
om.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
String s = om.writeValueAsString(myObject);
System.out.println(s);
myObject = om.readValue(s, MyObject2.class);
System.out.println(myObject);
{"intVal":3,"strVal":"3"}
MyObject2{intVal=3}
Allow serialization of empty POJOs
Following POJO does not have any Java Bean properties:
public class MyEmptyObject {
private int i = 10;
}
Using default:
MyEmptyObject myObject = new MyEmptyObject();
ObjectMapper om = new ObjectMapper();
String s = om.writeValueAsString(myObject);
System.out.println(s);
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class com.logicbig.example.MyEmptyObject 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:1191)
at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:312)
at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:71)
at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:33)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:3893)
at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3207)
at com.logicbig.example.DisableFailOnEmptyBeans.defaultOutput(DisableFailOnEmptyBeans.java:16)
Disabling FAIL_ON_EMPTY_BEANS
MyEmptyObject myObject = new MyEmptyObject();
ObjectMapper om = new ObjectMapper();
om.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
String s = om.writeValueAsString(myObject);
System.out.println(s);
{}
Assigning JSON empty string to null POJO
By default a JSON empty string ("") cannot be assign to a user defined POJO:
String s = "{\"myObjKey\":\"\"}";
System.out.println("input:\n" + s);
ObjectMapper om = new ObjectMapper();
Map<String, MyObject> myObject = om.readValue(s, new TypeReference<Map<String, MyObject>>() { });
System.out.println(myObject);
input:
{"myObjKey":""}
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.logicbig.example.MyObject` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('')
at [Source: (String)"{"myObjKey":""}"; line: 1, column: 13] (through reference chain: java.util.LinkedHashMap["myObjKey"])
at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1342)
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1031)
at com.fasterxml.jackson.databind.deser.ValueInstantiator._createFromStringFallbacks(ValueInstantiator.java:370)
at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromString(StdValueInstantiator.java:314)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1351)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:170)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:161)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBindStringKeyMap(MapDeserializer.java:527)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:364)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:29)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4001)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3011)
at com.logicbig.example.EnableEmptyStringAsNullPojo.defaultOutput(EnableEmptyStringAsNullPojo.java:19)
Enabling ACCEPT_EMPTY_STRING_AS_NULL_OBJECT
This feature assigns JSON empty string to the target object as null value.
String s = "{\"myObjKey\":\"\"}";
System.out.println("input:\n " + s);
ObjectMapper om = new ObjectMapper();
om.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
Map<String, MyObject> myObject = om.readValue(s, new TypeReference<Map<String, MyObject>>() { });
System.out.println(myObject);
input:
{"myObjKey":""}
{myObjKey=null}
This property does not mean that an empty JSON string will be assigned to Java String as null, but it means that it will assign the empty string to a null POJO.
Note that, by default Java simple objects are assigned as null without enabling this feature. Check out EmptyStringAsNullSimpleObject example in the project browser below.
Serialize java.util.Date as formatted String
Using default:
Date date = new Date();
ObjectMapper om = new ObjectMapper();
String s = om.writeValueAsString(Map.of("myDate", date));
System.out.println(s);
{"myDate":1512684866094}
Disabling WRITE_DATES_AS_TIMESTAMPS
Date date = new Date();
ObjectMapper om = new ObjectMapper();
om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
String s = om.writeValueAsString(Map.of("myDate", date));
System.out.println(s);
{"myDate":"2017-12-07T22:14:26.951+0000"}