I have implemented validation for Long
field and @PastOrPresent
validation
public class PastOrPresentValidator implements ConstraintValidator<PastOrPresent, Long>{
@Override
public boolean isValid(Long value, ConstraintValidatorContext context) {
if (value == null) {
return false;
}
return value <= System.currentTimeMillis();
}
}
public class MyDto {
@PastOrPresent
Long timestamp;
}
And got error:
HV000030: No validator could be found for constraint 'javax.validation.constraints.PastOrPresent' validating type 'java.lang.Long'. Check configuration for 'push.dto.timestamp'
But when I create custom annotation like @PastOrPresentLong
and use same validator code everything works.
Is there a way to add custom validator for javax.validation.constraints
annotation?
Just implementing the ConstraintValidator
interface isn't enough for your new validator to work. It should be somehow registered so that BeanValidation provider knows about it. This can be done via XML (see for more info here ):
<constraint-mappings
xmlns="http://xmlns.jcp.org/xml/ns/validation/mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/validation/mapping
http://xmlns.jcp.org/xml/ns/validation/mapping/validation-mapping-2.0.xsd"
version="2.0">
<!-- anything else -->
<constraint-definition annotation="javax.validation.constraints.PastOrPresent">
<validated-by include-existing-validators="true">
<value>org.mycompany.PastOrPresentLongValidator</value>
</validated-by>
</constraint-definition>
</constraint-mappings>
Then if you are using Hibernate Validator as BeanValidation provider you also have two more options - use service loader or programmatic definition. Using Service loader is the easiest way of adding new validator. All you need to do is create a META-INF/services/javax.validation.ConstraintValidator
file and add a FQCN of your validator to it. See detailed examples in this post under section "Use standard constraints for non standard classes" or in the doc . With programmatic approach you would have to do something like:
ConstraintMapping constraintMapping = configuration.createConstraintMapping();
constraintMapping
.constraintDefinition( PastOrPresent.class )
.validatedBy( PastOrPresentLongValidator.class );
And then add this constraint mapping to your configuration and create a validator from it:
Validator validator = configuration.addMapping( constraintMapping )
.buildValidatorFactory()
.getValidator();
But as I mentioned earlier - Service Loader is the easiest and quickest way to go.
A simpler declarative approach to linking the annotation to the validator is to specify the linkage through a Constraint(validatedBy) annotation.
@Retention(RUNTIME)
@Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE })
@Constraint(validatedBy = PastOrPrsentValidator.class)
public class PastOrPresentValidator implements ConstraintValidator<PastOrPresent, Long>{
...
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.