【问题标题】:Java Bean Validation (JSR303) constraints involving relationship between several bean propertiesJava Bean Validation (JSR303) 约束涉及多个 bean 属性之间的关系
【发布时间】:2010-12-14 14:11:52
【问题描述】:

假设我有以下简单的 java bean:

class MyBean {
   private Date startDate;
   private Date endDate;
   //setter, getters etc...
}

在 JSR 303 中是否有一种机制来创建自定义验证器来验证 startDate 必须在 endDate 之前的约束?

在我看来这是一个常见的用例,但我找不到这种多属性关系约束的任何示例。

【问题讨论】:

标签: java validation bean-validation


【解决方案1】:

如果您在 4.1 或更高版本中使用Hibernate Validator,则可以将@ScriptAssert 约束与脚本或表达式语言一起使用来表达这种约束。使用 JavaScript,您的示例将如下所示:

 @ScriptAssert(lang = "javascript", script = "_this.startDate.before(_this.endDate)")
 public class CalendarEvent {

      private Date startDate;

      private Date endDate;

      //...
 } 

您可以通过creating a custom constraint 为您选择的脚本语言获得更紧凑的语法:

@JexlAssert("_.startDate < _.endDate")
public class CalendarEvent {

    private Date startDate;

    private Date endDate;

    //...
}

【讨论】:

    【解决方案2】:

    【讨论】:

    • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
    【解决方案3】:

    答案是类级别的验证器。您可以定义可以放置在实体类上的自定义约束。在验证时,您将整个实例传递给 isValid() 方法。然后,您可以将两个日期相互比较。另请参阅 Hibernate 验证器 documentation

    【讨论】:

      【解决方案4】:

      我能想到一些可以尝试的方法。

      您可以使用适当的验证器创建一个 Constraint 类型本身的目标:

      @ValidateDateRange(start="startDate", end="endDate")
      public class MyBean {
      

      您可以将日期范围封装在一个类型中并验证:

      public class DateRange {    
        private long start;
        private long end;
      
        public void setStart(Date start) {
          this.start = start.getTime();
        }
      
        // etc.
      

      您可以添加一个执行检查的简单属性:

      public class MyBean {
        private Date startDate;
        private Date endDate;
      
        @AssertTrue public boolean isValidRange() {
          // TODO: null checks
          return endDate.compareTo(startDate) >= 0;
        }
      

      【讨论】:

        【解决方案5】:

        由于无法在 JSR 303 验证器中访问 bean,因此这是不可能的。

        一种解决方法是提供您自己的ConstraintValidatorContext 并通过引用您当前正在验证的bean 来扩展它。但我不确定您是否可以修改/覆盖各自的工厂。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-03-17
          • 2011-03-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多