简体   繁体   中英

Register new constraint validator for standard bean validation annotation

I'm wondering whether it's possible to register new constraint validator of some custom type to a annotation defined by Bean Validation specification. For example, let's image I have a class that accumulates several int values

public class IntContainer
{
  private int value1;
  private int value2;


  public int getValue1()
  {
    return value1;
  }


  public void setValue1(final int value1)
  {
    this.value1 = value1;
  }


  public int getValue2()
  {
    return value2;
  }


  public void setValue2(final int value2)
  {
    this.value2 = value2;
  }
}

I would like to register a custom constraint validator to support the @Positive annotation for this type (instead of created a custom annotation).

public class PositiveIntContainerValidator implements ConstraintValidator<Positive, IntContainer>
{
  @Override
  public boolean isValid(final IntContainer value, final ConstraintValidatorContext context)
  {
    //TODO: do some validation here based on IntContainer state
    return false;
  }
}

So that later I can use this:

@Positive
private IntContainer valueContainer;

A fully qualified name of your validator can be added to META-INF/services/javax.validation.ConstraintValidator file. This would allow Hibernate Validator to pick up your validator and it will be used for your custom types.

See more details if needed in this post (section "Use standard constraints for non standard classes")

It is not possible to use the @Positive annotation on your IntContainer class, as the validator does not support this data type.

Supported types for the @Positive annotation are:

  • BigDecimal
  • BigInteger
  • byte, short, int, long, float, double and their respective wrappers

See Annotation Type Positive .

You have two options here, you could write your own custom validator for IntContainer, or you could get the IntContainer from an entity that has it has a member variable and then validate it. Such as:

Bean: public class IntContainer {

@Positive
private int value1;
@Positive
private int value2;

public IntContainer() {

}

public IntContainer(int value1, int value2) {
    this.value1 = value1;
    this.value2 = value2;
}

public int getValue1() {
    return value1;
}

public void setValue1(final int value1) {
    this.value1 = value1;
}


public int getValue2() {
    return value2;
}


public void setValue2(final int value2) {
    this.value2 = value2;
}

}

Rest:

@POST
public Response postTest(TestRest testRest) {
    ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
    Validator validator = factory.getValidator();

    Set<ConstraintViolation<IntContainer>> constraintViolations = validator.validate(testRest.getIntContainer());
    System.out.println(constraintViolations.size());

    return Response.status(Response.Status.OK).entity(constraintViolations.size()).build();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM