Springboot表单验证确保一个日期不会出现在另一个日期之前?

时间:2017-05-04 14:34:30

标签: java validation spring-mvc spring-boot

按照本指南操作后:https://spring.io/guides/gs/validating-form-input/,我想进行表单验证,检查dateTo值是否在dateFrom值之前。如果有某种注释解决方案,那将是非常棒的。它们作为字符串存储在我的表单提供的空模型中。

@NotNull(message="You must select a date.")
@NotBlank(message="You must select a date.")
private String dateFrom;

@Min(dateFrom)
private String dateTo;

显然这不起作用,因为我们无法比较一个String是否小于另一个......是否有替代方案?问题是我想在表单验证检查中直接在UI中提供一条消息,就像我可以检查消息是空还是空白一样。

    // Create Request
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    String saveRequest(Principal principal, @Valid @ModelAttribute(value = "requestModel") RequestModel requestModel, BindingResult bindingResult, RedirectAttributes redirectAttributes) {
    ....
    if (bindingResult.hasErrors()) {
        // log.info("There are binding errors.");
        return "send";
    }
    ....

    // Format given date
    Date dateFrom = null;
    try {
        SimpleDateFormat formatter = new SimpleDateFormat(DateUtil.dateFormat);
        dateFrom = formatter.parse(requestModel.getDateFrom());
    } catch (ParseException e) {
        e.printStackTrace();
        return "send";
    }

    try {
        if (requestModel.getDateTo() != null && !(requestModel.getDateTo().isEmpty())) {
            SimpleDateFormat formatter = new SimpleDateFormat(DateUtil.dateFormat);
            Date dateTo = formatter.parse(requestModel.getDateTo());

            // Check if dateTo is before dateFrom
            if (!dateTo.before(dateFrom)) {
                // If not (proper case), set the date
                requestDOOb.setDateTo(dateTo);
            } else {
                // Improper case, log error
                //TODO Update UI?
                log.info("dateTo cannot come before dateFrom");
                return "send";
            }

        } else {
            requestDOOb.setDateTo(dateFrom);
        }
    } catch (ParseException e) {
        e.printStackTrace();
        return "send";
    }

我不想在POST方法本身中执行验证...

更新

@AssertTrue(message="The end date cannot come before the initial date.")
private boolean isValid() {
    return !dateTo.before(dateFrom) && this.dateFrom.before(this.dateTo);
}

public Date getDateFrom() {
    return dateFrom;
}

public void setDateFrom(Date dateFrom) {
    this.dateFrom = dateFrom;
}

public Date getDateTo() {
    return dateTo;
}

public void setDateTo(Date dateTo) {
    this.dateTo = dateTo;
}

如上所述呢?

1 个答案:

答案 0 :(得分:1)

您可以创建自己的验证器/验证注释(请参阅https://docs.jboss.org/hibernate/validator/5.0/reference/en-US/html/chapter-bean-constraints.html#d0e371

注释:

@Target({ElementType.TYPE}) 
@Retention(RetentionPolicy.RUNTIME) 
@Constraint(validatedBy=YourDateValidator.class) 
public @interface ValidDates {
    String message() default "{message.id}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

验证

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class YourDateValidator implements ConstraintValidator< ValidDates, 
    TypeToBeValidated> {

    @Override
    public void initialize(ValidDates constraintAnnotation) {
    }

    @Override
    public boolean isValid(TypeToBeValidated value, ConstraintValidatorContext context) 
    {
        < validation code, returning true for a valid value >
    }

}

用法:

@ValidDates
class TypeToBeValidated {
    private String dateFrom;
    private String dateTo;
}