Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

validating json using constraints annotations is not working

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 ?

like image 441
igx Avatar asked Nov 21 '14 14:11

igx


People also ask

Which annotations is used for validation?

The @Valid annotation applies validation rules on the provided object. The BindingResult interface contains the result of validation.

Is @valid and @validated the same?

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.

What does @NotNull annotation Bean in Bean property?

@NotNull validates that the annotated property value is not null. @AssertTrue validates that the annotated property value is true.


1 Answers

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());
}
  • See Getting started with Hibernate Validator for some more examples
like image 175
Paul Samsotha Avatar answered Oct 06 '22 23:10

Paul Samsotha