【问题标题】:Springboot form validation for ensuring one date does not come before another?Spring Boot 表单验证以确保一个日期不会出现在另一个日期之前?
【发布时间】:2017-10-02 19:21:15
【问题描述】:

遵循本指南: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;

显然这行不通,因为我们无法比较一个字符串是否比另一个小...有替代方案吗?问题是我想从表单验证检查中直接在 UI 中提供一条消息,就像我如何检查消息是 null 还是空白一样。

    // 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;
}

像上面这样的呢?

【问题讨论】:

  • 您是在寻找一个可以让您指定要比较的任意属性的注释,还是一个类级别的注释 (@ValidDates) 就足够了?
  • 我在上面添加了一个可能的解决方案。我基本上是想在 Springboot 表单验证绑定中比较结束日期​​是否早于初始日期。
  • 你的方法很好,很好,很简单。有什么不工作吗?如果您想稍后重用它,您始终可以使用自定义验证器进行自定义注释。那时可能不得不引入一个接口。类似HasFromToDates
  • 我唯一的问题是我希望模型中发送的日期是字符串,然后再转换它们,所以自定义验证器会更好,因为我可以将字符串解析为日期,运行检查,然后更新 UI。

标签: java validation spring-mvc spring-boot


【解决方案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;
}

【讨论】:

  • 有趣的方法,但我不知道如何将两个日期传递给验证器以便比较它们......
  • @santafebound TypeToBeValidated 是包含fromDatetoDate 的bean。这是一个类型级别的注释,你用它来注释类,而不是单个属性。
猜你喜欢
  • 2015-04-30
  • 1970-01-01
  • 1970-01-01
  • 2016-01-11
  • 2015-11-17
  • 2012-05-20
  • 1970-01-01
  • 2019-04-02
  • 2015-09-29
相关资源
最近更新 更多