如何使用javax.validation注解验证From小于To?
from is Less Than to Using javax.validation Annotations Got it, so you already have basic null and minimum value checks on your from and to fields, and now need to add a cross-field validation to ensure from is strictly less than to. Since this involves comparing two fields, you can't use a standard field-level annotation—you'll need a custom class-level constraint. Here's a step-by-step breakdown:
1. Create a Custom Constraint Annotation
First, define your own annotation to mark the class that needs this cross-field check. This annotation will trigger our custom validation logic.
import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.*; @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = FromLessThanToValidator.class) public @interface FromLessThanTo { String message() default "From must be less than To"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
2. Implement the Constraint Validator
Next, write the actual validation logic that checks if from is less than to. This class implements ConstraintValidator and defines the rules for our custom annotation.
import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; // Replace "YourEntity" with the actual name of your entity class public class FromLessThanToValidator implements ConstraintValidator<FromLessThanTo, YourEntity> { @Override public boolean isValid(YourEntity entity, ConstraintValidatorContext context) { // First, we should check if both fields are not null (since you already have @NotNull on them) // But it's safe to add a null check here to avoid NPE in case the basic validations are skipped if (entity.getFrom() == null || entity.getTo() == null) { return true; // Let @NotNull handle the null checks separately } return entity.getFrom() < entity.getTo(); } }
3. Apply the Annotation to Your Entity
Finally, add the custom class-level annotation to your entity class. This tells the validator to run our cross-field check alongside the existing field-level validations.
import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; @FromLessThanTo // Add this class-level annotation public class YourEntity { @NotNull(message = "From can't be null") @Min(value = 1, message = "From must be greater than zero") private Long from; @NotNull(message = "To can't be null") @Min(value = 1, message = "To must be greater than zero") private Long to; // Getters and setters here public Long getFrom() { return from; } public void setFrom(Long from) { this.from = from; } public Long getTo() { return to; } public void setTo(Long to) { this.to = to; } }
Key Notes
- Class-level vs Field-level: Cross-field validations require class-level annotations because they depend on multiple fields in the entity.
- Null Handling: The validator returns
trueif either field is null—this lets your existing@NotNullannotations handle those cases separately, so you don't get duplicate error messages. - Integration: If you're using Spring Boot, make sure your validator class is in a package that's scanned by Spring (or add
@Componentto it) so it's registered properly.
内容的提问来源于stack exchange,提问作者Shahid Ghafoor

