Reputation: 1331
i have a class which is working as the request payload for my api . I need to validate the one of my field "dateOfBirth". Using the javax.validation.past i am checkking the date is not future date but i also want to validate that the date must not be less than 1900-01-01 .
Is there any way using javax.validation api we can do it?
Class Employee{
----
---
@Past(message="date of birth must be less than today")
@DateTimeFormate( pattern="yyyy-MM-dd")
private Date dateOfBirth;
//constuctor
//getter & setter
}
Upvotes: 0
Views: 19734
Reputation: 158
You can create your validation logic that specifies that the birthdate be in the past and after your date like so:
public class BirthDateValidator implements ConstraintValidator<BirthDate, LocalDate> {
private LocalDate OLDEST_ALLOWED_DATE = LocalDate.of(1900, 01, 01);
@Override
public boolean isValid(LocalDate date, ConstraintValidatorContext context) {
LocalDate currentDate = LocalDate.now();
return currentDate.isAfter(date) && date.isAfter(OLDEST_ALLOWED_DATE);
}
}
Then you can bind this validation logic to your custom validator interface like so:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = BirthDateValidator.class)
public @interface BirthDate {
String message() default "Birth Date must be in the past";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Now you can apply this validator to the field you're interested in using the annotation
Upvotes: 0
Reputation: 64
The post from https://stackoverflow.com/a/54258098/15541786 is great. I did it in my project and it's working. Just to avoid errors in console, add also to interface
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
So, working example:
@Target(ElementType.FIELD)
@Retention(RUNTIME)
@Constraint(validatedBy = DateValidator.class)
@Documented
public @interface IsAfter{
String message() default "{message.key}";
String current();
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Upvotes: 0
Reputation: 17289
You should define custom annotation for this propose. something like bellow:
@Target(ElementType.FIELD)
@Retention(RUNTIME)
@Constraint(validatedBy = DateValidator.class)
@Documented
public @interface IsAfter{
String message() default "{message.key}";
String current();
}
and also define a custom validator like this:
public class DateValidator implements ConstraintValidator<IsAfter, LocalDate> {
String validDate;
@Override
public void initialize(IsAfter constraintAnnotation) {
validDate = constraintAnnotation.current();
}
@Override
public boolean isValid(LocalDate date, ConstraintValidatorContext constraintValidatorContext) {
String[] splitDate = validDate.split("-");
return date.isAfter(LocalDate.of(Integer.valueOf(splitDate[0]), Integer.valueOf(splitDate[1]), Integer.valueOf(splitDate[2])));
}
}
and use this annotation:
@Past(message="date of birth must be less than today")
@IsAfter(current = "1900-01-01")
@DateTimeFormate( pattern="yyyy-MM-dd")
private Date dateOfBirth;
note: I haven't tested this annotation!
Upvotes: 1