【问题标题】:Cross-field Java Bean Validation doesn't validate field from JSF跨字段 Java Bean 验证不验证来自 JSF 的字段
【发布时间】:2016-10-25 21:10:34
【问题描述】:

我正在尝试实现类似 DateRange 验证器的东西来验证,如果开始日期早于结束日期。我已经为验证、验证器类等定义了注释。不幸的是,当我尝试访问或设置验证对象(通过 UI)中的某些内容时,不会调用验证。我究竟做错了什么 ?我定义了以下类:

TimePeriod.java

@Constraint(validatedBy = DateRangeValidator.class)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface TimePeriod {

     String message() default "something";
        Class<?>[] groups() default {};
        Class<? extends Payload>[] payload() default {};

}

DateRangeValidator.java

    public class DateRangeValidator implements ConstraintValidator<TimePeriod, DateRange>{

    TimePeriod constraintAnnotation;

    @Override
    public void initialize(TimePeriod constraintAnnotation) {
        this.constraintAnnotation = constraintAnnotation;
    }

    @Override
    public boolean isValid(DateRange value, ConstraintValidatorContext context) { 
            throw new RuntimeException("Some exception");

    }
}

DateRange.java

public class DateRange {

    private Date startDate;
    private Date endDate;

    public DateRange(Date start, Date end){
        this.startDate = start;
        this.endDate = end;
    }

    public Date getStartDate() {
        return startDate;
    }
    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }
    public Date getEndDate() {
        return endDate;
    }
    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }

}

我使用 Primefaces 日历元素来选择开始和结束日期。这个片段是:

<p:calendar id="startdateWizard"    
            value="#{DRBean.dateRange.startDate}"
            showButtonPanel="true"
            required="true"
>

DRBean.java

@Named
@ViewScoped
public class PFSBean implements Serializable {

    @TimePeriod
    private DateRange dateRange = new DateRange(new Date(), new Date()) ;


  public DateRange getDateRange() {
    return dateRange;
  }

  public void setDateRange(DateRange dateRange) {
    this.dateRange = dateRange;
  }
}

可能是因为没有直接设置 dateRange 对象 - 只设置了其中一个字段。如果是这样,如何改变它以达到预期的效果(在 DateRange 对象上验证以确保开始日期始终在结束日期之前)

【问题讨论】:

    标签: java primefaces jsf-2 bean-validation


    【解决方案1】:

    经过一些研究,我意识到对于这种跨字段验证,使用 JSR303 bean 验证,需要在类级别进行验证。不幸的是,在 JSF 2.3 版本之前,此选项不可用,因为它在此 post 中声明。因此,仅使用 JSF 是不可能的。然而,它可以在 Omnifaces 的帮助下完成。可以在Omnifaces showcase 上找到类级别验证的绝佳示例。将此解决方案应用于我的任务就像在带有日历元素的表单中添加 &lt;o:validateBean value="#{pFSBean.dateRange}"/&gt; 一样简单:

        <h:form>
            <p:messages id="messages" autoUpdate="true"/>
            <p:panel id="panel1">
                <h:panelGrid columns="2">
                    <p:calendar id="startdateWizard"    
                                value="#{pFSBean.dateRange.startDate}"
                                showButtonPanel="true"
                                required="true"
                    >   
                    </p:calendar>
                    <p:calendar id="enddateWizard"
                                name="enddateWizard"
                                value="#{pFSBean.dateRange.endDate}"
                                        required="true" showButtonPanel="true"
                    >                           
                    </p:calendar>
                </h:panelGrid>
            </p:panel>        
            <o:validateBean value="#{pFSBean.dateRange}"/> 
            <p:commandButton process="@(form)" update="@(form)" 
                                 value="Process form"/>
    
       </h:form>
    

    @TimePeriod 注释也移动到类级别:

    @TimePeriod
    public class DateRange {
       ....
       ....
    }
    

    TYPE 的注解目标应该添加到注解定义中。就这样。现在将调用验证器类中的方法isValid。当然这不是完美的解决方案,因为需要额外的工具,但不幸的是没有它是不可能的

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-30
      • 2012-08-11
      相关资源
      最近更新 更多