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 ...
}