Home > Net >  Is it possible to make Jackson ObjectMapper deserialization fail when no property is mapped resultin
Is it possible to make Jackson ObjectMapper deserialization fail when no property is mapped resultin

Time:05-21

I'm struggling with a problem: is it possible to configure Jackson to throw an error if no field is mapped?

Example: deserializing an empty object("{}") or without any of the fields that the target object contains.

CodePudding user response:

I always check if some fields is null after get Jackson deserialize api. But i think you can extends Jackson deserializer to rewrite deserialize method to achieve your purpose.

CodePudding user response:

Check if it equals to empty object:

    @NoArgsConstructor
    @Getter
    @Setter
    @ToString
    @EqualsAndHashCode
    @JsonIgnoreProperties
    public class Foo {
        private String a;
        private String b;
        private String c;
        private String d;
    }


    public class FooMain {
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
    private static final Foo EMPTY_FOO = new Foo();
    
    public static void main(String[] args) {
        try {
            // This attempt will throw an exception:        
            Optional.ofNullable(OBJECT_MAPPER.readValue("{}", Foo.class))
                    .filter(foo1 -> !foo1.equals(EMPTY_FOO))
                    .orElseThrow(IllegalArgumentException::new);
            // This attempt will not throw an exception:
            Optional.ofNullable(OBJECT_MAPPER.readValue("{a:\"123\"}", Foo.class))
                    .filter(foo1 -> !foo1.equals(EMPTY_FOO))
                    .orElseThrow(IllegalArgumentException::new);

        } catch (JsonProcessingException e) {
            // cannot deserialize json string to FOO  
        }
    }
}

CodePudding user response:

if all from as set of fields are required:

If using the constructor for deserializing the object you can use required from @JsonProperty annotation.

For example, for a class Foo, a field name is required:

class Foo
{
    String name;
    Integer number; 
    
    @JsonCreator
    public Foo(
       @JsonProperty(value = "name", required = true) String name,
       @JsonProperty(value = "number") Integer number)
    {
        this.name = name;
        this.number = number;
    }
    // ... more methods ...
}

When trying to deserialize from an JSON with no name property, it will fail with MismatchedInputException:

objectMapper.readValue("{}", Foo.class); // FAILURE

Note that if JSON object explicitly sets the field as null, it will succeed:

objectMapper.readValue("{\"name\": null}", Foo.class); // SUCCESS

if any from a set of fields must be present:

This is a simple variation of the previous case, as we can put validation logic inside the @JsonCreator-annotated constructor.

For example:

class Foo
{
    String name;
    Integer number;
     
    @JsonCreator
    public Foo(
       @JsonProperty("name") String name,
       @JsonProperty("number") Integer number)
    {
       if (name == null && number == null)
            throw new IllegalArgumentException("at least one of (name, number) fields must be non-null");
            
       this.name = name;
       this.number = number;
    }
    // ... more methods ...    
}
  • Related