Jackson fail deserialization if field is not present

Viewed 4604

I have a pojo like

class Pojo {
    private String string;

    public String getString() { return string; }

    @JsonSetter(nulls = Nulls.FAIL)
    public void setString(String string) {
        this.string = string;
    }
}

I want to make jackson fail when deserializing if the string field is null or absent. (i.e. {"string":null} or {})

As you can see, I've succeeded in the first goal with the JsonSetter annotation. What I am hoping for now is something like that but for a missing property. I found a few other questions asking similar things but they were quite old and referenced features that might be implemented in the future. With the recent release of jackson 2.9, I was hoping maybe this is now possible.

2 Answers

@JsonProperty has a required element that can be used

to ensure existence of property value in JSON

Unfortunately, Jackson currently (2.9) only supports it for use with @JsonCreator annotated constructors or factory methods. Since @JsonSetter only works with setters, you'll have to do the null validation yourself.

For example, you'd define a constructor like

@JsonCreator
public Pojo(@JsonProperty(value = "string", required = true) String string) {
    if (string == null) {
        throw new IllegalArgumentException("string cannot be null");
    }
    this.string = string;
}

If the property is present, but set to null, Jackson would throw an InvalidDefinitionException that wraps the IllegalArgumentException thrown in the constructor.

If the property is absent, Jackson would throw a MismatchedInputException stating that a property is missing.

Both of these exceptions are subtypes of JsonMappingException, so you can easily deal with them the same way.


With this solution, you could also get rid of the setter altogether and make the field final if that suited your design better.

You may perform bean validation here by annotating the field of interest with @NotNull. You may remove the annotation from your setter.

class Pojo {

    @NotNull
    private String string;

    public String getString() { return string; }

    public void setString(String string) {
        this.string = string;
    }

}

Similarly if you want to fail the validation for other constraints like size, pattern etc, you may use similar equivalent annotations available here.

Related