I am trying to validate a json when deserialize it using constraints annotations but it doesn't seem to work. for example
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
public class SimpleFooRequest {
@NotNull
@JsonProperty(value = "count")
@Min(value = 100,message = "must be min 10")
private Integer count;
@NotNull
private String name;
public String getName() {return name; }
public void setName(String name) { this.name = name; }
public Integer getCount() {return count;}
public void setCount(Integer count) {this.count = count;}
}
when trying to unmarshal the json
@Test
public void testFooRequest() throws Exception
{
String fooJson = {"count":-10}
ObjectMapper mapper = new ObjectMapper()
SimpleFooRequest request = mapper.readValue(fooJson,SimpleFooRequest.class);
assert request.getCount().equals(-10);//expected fail but it pass !!!
}
it seems to pass although I expected that the assertion will fail due to the count min value limitation . I also tried to put the annotations on the setters but got same results
I have <mvc:annotation-driven />
and hibernate-validator-4.3.1.Final.jar
in my dependencies
I know that I can create custom validator but I thought that for simple validations I can use the annotations .
what do I need to do to make it work ?
The @Valid annotation applies validation rules on the provided object. The BindingResult interface contains the result of validation.
The @Valid annotation ensures the validation of the whole object. Importantly, it performs the validation of the whole object graph. However, this creates issues for scenarios needing only partial validation. On the other hand, we can use @Validated for group validation, including the above partial validation.
@NotNull validates that the annotated property value is not null. @AssertTrue validates that the annotated property value is true.
Annotations are just meta-data. They're not programs that can perform any validation. The validator is the program that will make use of the meta-data. In a container, the container will manage the validator. In basic unit tests or standalones, you will need to manage the validator yourself.
That being said, even a validator cannot stop the object from being created/populated (as you seem to be asserting in your test). It just validates that the value is valid. If not, the validator throws an exception and/or lists some constraint violations. Either the container, or you should handle what to do with the exceptions/violations.
And AFAIK, there's no ObjectMapper
configuration for automatic JSR-303 support while deserializing
A better unit test, might look something like
/* ----- Using the Hibernate Validator implementation ----- */
@Test
public void testInvalidCount() throws Exception {
final String json = "{\"count\":-10, \"name\":\"Stack\"}";
ObjectMapper mapper = new ObjectMapper();
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
SimpleFooRequest request = mapper.readValue(
json, SimpleFooRequest.class);
Set<ConstraintViolation<SimpleFooRequest>> violations
= validator.validate(request);
Assert.assertEquals(1, violations.size());
Assert.assertEquals("must be min 10",
violations.iterator().next().getMessage());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With