Avoid UnrecognizedPropertyException by Ignoring Unknown Fields

In this article, we will explore how to handle situations when you’re deserializing JSON data into Java objects using Jackson, and the JSON contains fields that are not present in the Java class.

We’ll continue to use the Person class for our examples:

import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;
import java.io.IOException;

public class Person {
    private Long id;
    private String name;
    private String dateOfBirth;
    private List<Person> friends;
    // Getters and setters (not shown for brevity)
}

UnrecognizedPropertyException

By default, Jackson throws an UnrecognizedPropertyException when it encounters unknown fields during deserialization. We have three ways to deal with this kind of situation.

Configure ObjectMapper

We can configure the ObjectMapper to ignore unknown fields using the DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES.

public static void main(String[] args) throws IOException {
    String json = "{\"id\":1,\"name\":\"Alice\",\"dateOfBirth\":\"1990-05-15\",\"city\":\"New York\"}";

    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    try {
        Person person = objectMapper.readValue(json, Person.class);
        System.out.println("Deserialized Person object: " + person.getName());
    } catch (UnrecognizedPropertyException e) {
        System.out.println("Unrecognized property encountered: " + e.getPropertyName());
    }
}

In this example, the JSON data contains an additional field city, which is not present in the Person class. By configuring the ObjectMapper to ignore unknown properties, Jackson successfully deserializes the JSON data without throwing an exception.

Annotate Class with @JsonIgnoreProperties

We can also use Jackson annotations to ignore unknown fields during deserialization. In below example, we will demonstrate how to use the @JsonIgnoreProperties annotation to achieve this.


@JsonIgnoreProperties(ignoreUnknown = true) // the only change, no additional changes needed
public class Person {
    private Long id;
    private String name;
    private String dateOfBirth;
    private List<Person> friends;
    // Getters and setters (not shown for brevity)
}

Here, we’ve added the @JsonIgnoreProperties(ignoreUnknown = true) annotation to the Person class. This annotation tells Jackson to ignore any unknown fields during deserialization.

public static void main(String[] args) throws IOException {
    String json = "{\"id\":1,\"name\":\"Alice\",\"dateOfBirth\":\"1990-05-15\",\"city\":\"New York\"}";
    ObjectMapper objectMapper = new ObjectMapper();
    Person person = objectMapper.readValue(json, Person.class);
    System.out.println("Deserialized Person object: " + person.getName());
}

With the @JsonIgnoreProperties annotation applied, Jackson will ignore the city``` field, even without the explicit configuration in the ObjectMapper`.

Create a Custom Handler

If we want more control over how unknown fields are handled, we can use a custom deserialization.

Here’s an example where we capture and log the unknown fields:

    public static void customHandler() throws IOException {
        String json = "{\"id\":1,\"name\":\"Alice\",\"dateOfBirth\":\"1990-05-15\",\"city\":\"New York\"}";

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.addHandler(new DeserializationProblemHandler() {
            @Override
            public boolean handleUnknownProperty(DeserializationContext ctxt,
                                                 JsonParser jp,
                                                 JsonDeserializer<?> deserializer,
                                                 Object bean, String propertyName) {
                System.out.println("Unknown property found: " + propertyName);
                return true; // Indicates that the unknown property has been handled
            }
        });

        Person person = objectMapper.readValue(json, Person.class);

        System.out.println("Deserialized Person object: " + person);
    }

Read More