Cross field validation with Hibernate Validator (JSR 303)

前端 未结 15 1776
渐次进展
渐次进展 2020-11-22 02:37

Is there an implementation of (or third-party implementation for) cross field validation in Hibernate Validator 4.x? If not, what is the cleanest way to implement a cross fi

15条回答
  •  别那么骄傲
    2020-11-22 02:59

    You guys are awesome. Really amazing ideas. I like Alberthoven's and McGin's most, so I decided to combine both ideas. And develop some generic solution to cater all cases. Here is my proposed solution.

    @Documented
    @Constraint(validatedBy = NotFalseValidator.class)
    @Target({ElementType.METHOD, ElementType.FIELD,ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface NotFalse {
    
    
        String message() default "NotFalse";
        String[] messages();
        String[] properties();
        String[] verifiers();
    
        Class[] groups() default {};
    
        Class[] payload() default {};
    
    }
    

    public class NotFalseValidator implements ConstraintValidator {
        private String[] properties;
        private String[] messages;
        private String[] verifiers;
        @Override
        public void initialize(NotFalse flag) {
            properties = flag.properties();
            messages = flag.messages();
            verifiers = flag.verifiers();
        }
    
        @Override
        public boolean isValid(Object bean, ConstraintValidatorContext cxt) {
            if(bean == null) {
                return true;
            }
    
            boolean valid = true;
            BeanWrapper beanWrapper = PropertyAccessorFactory.forBeanPropertyAccess(bean);
    
            for(int i = 0; i< properties.length; i++) {
               Boolean verified = (Boolean) beanWrapper.getPropertyValue(verifiers[i]);
               valid &= isValidProperty(verified,messages[i],properties[i],cxt);
            }
    
            return valid;
        }
    
        boolean isValidProperty(Boolean flag,String message, String property, ConstraintValidatorContext cxt) {
            if(flag == null || flag) {
                return true;
            } else {
                cxt.disableDefaultConstraintViolation();
                cxt.buildConstraintViolationWithTemplate(message)
                        .addPropertyNode(property)
                        .addConstraintViolation();
                return false;
            }
    
        }
    
    
    
    }
    

    @NotFalse(
            messages = {"End Date Before Start Date" , "Start Date Before End Date" } ,
            properties={"endDateTime" , "startDateTime"},
            verifiers = {"validDateRange" , "validDateRange"})
    public class SyncSessionDTO implements ControllableNode {
        @NotEmpty @NotPastDate
        private Date startDateTime;
    
        @NotEmpty
        private Date endDateTime;
    
    
    
        public Date getStartDateTime() {
            return startDateTime;
        }
    
        public void setStartDateTime(Date startDateTime) {
            this.startDateTime = startDateTime;
        }
    
        public Date getEndDateTime() {
            return endDateTime;
        }
    
        public void setEndDateTime(Date endDateTime) {
            this.endDateTime = endDateTime;
        }
    
    
        public Boolean getValidDateRange(){
            if(startDateTime != null && endDateTime != null) {
                return startDateTime.getTime() <= endDateTime.getTime();
            }
    
            return null;
        }
    
    }
    

提交回复
热议问题