mushroom
mushroom

Reputation: 6289

Configure Jackson to throw an exception when a field is missing

I have a class like this:

public class Person {
  private String name;
  public String getName(){
    return name;
  }
}

I am using an ObjectMapper configured like this:

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

I have a String str that contains this { "address" : "something" }. Note that there is no "name" field in the json. If I do something like this:

mapper.readValue(str, Person.class);

then I actually get back a Person object with name set to null. Is there a way to configure the mapper to throw an exception instead, or return a null reference instead of a Person? I want Jackson to consider missing fields a failure and don't want to do explicit null checks on the resulting object's fields.

Upvotes: 32

Views: 35951

Answers (3)

Kev
Kev

Reputation: 587

I had a similar problem, after deserialization I wanted to know if everything is fine. This method iterates over all fields with a JsonProperty Annotation, checks if it is not null and look deeper if this class in the recursive list (to avoid infinite loops).

private void checkIfFieldsAreNotNull(Object o, List<Class> recursive) {
    Arrays.asList(o.getClass().getDeclaredFields()).stream().filter(field -> field.isAnnotationPresent(JsonProperty.class)).forEach(field -> {
        field.setAccessible(true);
        try {
            assertNotNull(field.get(o));
            if(recursive.contains(field.getType())) {
                checkIfFieldsAreNotNull(field.get(o), recursive);
            }
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    });
}

Upvotes: 0

zopieux
zopieux

Reputation: 2901

As of Jackson 2.6, there is a way, but it does not work on class attribute annotations, only constructor annotations:

/* DOES *NOT* THROW IF bar MISSING */
public class Foo {    
    @JsonProperty(value = "bar", required = true)
    public int bar;
}

/* DOES THROW IF bar MISSING */
public class Foo {
    public int bar;
    @JsonCreator
    public Foo(@JsonProperty(value = "bar", required = true) int bar) {
        this.bar = bar;
    }
}

Upvotes: 41

vtor
vtor

Reputation: 9319

Unfortunately this is not supported by Jackson at this moment.

Solution could be to add validation in your constructor. As ideally if you don't want to have those values serialized as null's , it does mean you shouldn't have them as null's at all (constructed in other way). For example,

public class Person {
  private String name;
  public Person() {
     checkNotNull(name);
  }
} 

however this might not fittable in all situations, specially if you are using your object's other than through serializing/deserializing.

Though they have required attribute in @JsonProperty annotation, it is not supported during deserialization at all, and has been introduced only for decorating JSON schemas. See this topic

Upvotes: 6

Related Questions