
Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:
Once the early-adopter seats are all used, the price will go up and stay at $33/year.
Last updated: December 8, 2021
In this tutorial, we’re going to take a look at the unmarshalling process with Jackson 2.x, specifically how to deal with JSON content with unknown properties.
To dig deeper and learn other cool things we can do with Jackson, we can check out the main Jackson tutorial.
JSON input comes in all shapes and sizes, and most of the time, we need to map it to predefined Java objects with a set number of fields. The goal is to simply ignore any JSON properties that cannot be mapped to an existing Java field.
For example, say we need to unmarshal JSON to the following Java entity:
public class MyDto {
private String stringValue;
private int intValue;
private boolean booleanValue;
// standard constructor, getters and setters
}
Trying to unmarshal a JSON with unknown properties to this simple Java Entity will lead to a com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:
@Test(expected = UnrecognizedPropertyException.class)
public void givenJsonHasUnknownValues_whenDeserializingAJsonToAClass_thenExceptionIsThrown()
throws JsonParseException, JsonMappingException, IOException {
String jsonAsString =
"{\"stringValue\":\"a\"," +
"\"intValue\":1," +
"\"booleanValue\":true," +
"\"stringValue2\":\"something\"}";
ObjectMapper mapper = new ObjectMapper();
MyDto readValue = mapper.readValue(jsonAsString, MyDto.class);
assertNotNull(readValue);
}
This will fail with the following exception:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:
Unrecognized field "stringValue2" (class org.baeldung.jackson.ignore.MyDto),
not marked as ignorable (3 known properties: "stringValue", "booleanValue", "intValue"])
We can now configure the full ObjectMapper to ignore unknown properties in the JSON:
new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
We should then be able to read this kind of JSON into a predefined Java entity:
@Test
public void givenJsonHasUnknownValuesButJacksonIsIgnoringUnknownFields_whenDeserializing_thenCorrect()
throws JsonParseException, JsonMappingException, IOException {
String jsonAsString =
"{\"stringValue\":\"a\"," +
"\"intValue\":1," +
"\"booleanValue\":true," +
"\"stringValue2\":\"something\"}";
ObjectMapper mapper = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
MyDto readValue = mapper.readValue(jsonAsString, MyDto.class);
assertNotNull(readValue);
assertThat(readValue.getStringValue(), equalTo("a"));
assertThat(readValue.isBooleanValue(), equalTo(true));
assertThat(readValue.getIntValue(), equalTo(1));
}
We can also mark a single class as accepting unknown fields, instead of the entire Jackson ObjectMapper:
@JsonIgnoreProperties(ignoreUnknown = true)
public class MyDtoIgnoreUnknown { ... }
Now we should be able to test the same behavior as before. The unknown fields are simply ignored, and only known fields are mapped:
@Test
public void givenJsonHasUnknownValuesButUnknownFieldsAreIgnoredOnClass_whenDeserializing_thenCorrect()
throws JsonParseException, JsonMappingException, IOException {
String jsonAsString =
"{\"stringValue\":\"a\"," +
"\"intValue\":1," +
"\"booleanValue\":true," +
"\"stringValue2\":\"something\"}";
ObjectMapper mapper = new ObjectMapper();
MyDtoIgnoreUnknown readValue = mapper
.readValue(jsonAsString, MyDtoIgnoreUnknown.class);
assertNotNull(readValue);
assertThat(readValue.getStringValue(), equalTo("a"));
assertThat(readValue.isBooleanValue(), equalTo(true));
assertThat(readValue.getIntValue(), equalTo(1));
}
Similar to additional unknown fields, unmarshalling an incomplete JSON, a JSON that doesn’t contain all the fields in the Java class, isn’t a problem with Jackson:
@Test
public void givenNotAllFieldsHaveValuesInJson_whenDeserializingAJsonToAClass_thenCorrect()
throws JsonParseException, JsonMappingException, IOException {
String jsonAsString = "{"stringValue":"a","booleanValue":true}";
ObjectMapper mapper = new ObjectMapper();
MyDto readValue = mapper.readValue(jsonAsString, MyDto.class);
assertNotNull(readValue);
assertThat(readValue.getStringValue(), equalTo("a"));
assertThat(readValue.isBooleanValue(), equalTo(true));
}
In this article, we discussed deserializing a JSON with additional, unknown properties using Jackson.
This is one of the most common things to configure when working with Jackson, since we often need to map JSON results of external REST APIs to an internal Java representation of the entities of the API.