Reputation: 1033
I am trying to use Jackson library for deserialization since I have a scenario wherein I have to validate for null
values in many JsonProperty if it is set as required=true
.
Here is the code snippet.
public class JacksonValidator {
private static final ObjectMapper MAPPER = new ObjectMapper();
public static void main(String[] args) {
// Should succeed since all properties have value and required=true holds good
validate("{\"id\": \"1\",\"age\": 26,\"name\": \"name1\"}");
// Should throw exception since name is null (because of required=true)
validate("{\"id\": \"2\",\"age\": 28,\"name\": null}");
// Should throw exception since id is null (because of required=true)
validate("{\"id\": null,\"age\": 27,\"name\": \"name2\"}");
}
public static void validate(String json) {
try {
Customer customer = MAPPER.readValue(json, Customer.class);
System.out.println(customer);
}
catch (IOException e) {
throw new DeserializationException(String.format("Validation failed. Unable to parse json %s", json), e);
}
}
@Setter
@Getter
@ToString
public static class Customer {
private String id;
private Integer age;
private String name;
@JsonCreator
public Customer(@JsonProperty(value = "id", required = true) String id,
@JsonProperty(value = "age", required = false) Integer age,
@JsonProperty(value = "name", required = true) String name) {
this.id = id;
this.age = age;
this.name = name;
}
}
}
As you can see in the above code, I am trying to deserialize JSON
into Customer
class. If the required
property is set to true
for a JsonProperty
and while deserialization if this property encounters null
(for id
and name
field in the above code), I have to throw a custom DeserializationException
.
And also I need to have null
values processed(shouldn't fail) for fields where required=false
is set in JsonProperty(for age
field).
Here I cannot use MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL)
since I need to process null
values for required=false
fields.
Please let me know how this could be achieved using ObjectMapper.readValue
method or any other method that holds good here.
Any suggestions would be appreciated.
Upvotes: 1
Views: 4580
Reputation: 2278
You can't use @JsonProperty
for null validation. It only checks whether value is present or not. From javadocs
Property that indicates whether a value (which may be explicit null) is expected for property during deserialization or not.
For null validation you can use Bean validation JSR-380. Hibernate example:
Maven dependencies:
<!-- Java bean validation API - Spec -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<!-- Hibernate validator - Bean validation API Implementation -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.11.Final</version>
</dependency>
<!-- Verify validation annotations usage at compile time -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator-annotation-processor</artifactId>
<version>6.0.11.Final</version>
</dependency>
<!-- Unified Expression Language - Spec -->
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.1-b06</version>
</dependency>
<!-- Unified Expression Language - Implementation -->
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.el</artifactId>
<version>2.2.6</version>
</dependency>
Then you can use it like:
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<Customer>> constraintViolations = validator.validate(customer);
if (constraintViolations.size() > 0) {
throw new DeserializationException(String.format("Validation failed. Unable to parse json %s", json), e);
}
Upvotes: 1