2016-10-25 92 views
0

我试图实现类似DateRange验证器来验证,如果开始日期是在结束日期之前。我已经为验证,验证器类等定义了注释。 Unforunatelly当我尝试访问或设置验证对象(通过UI)中的验证不被调用。我究竟做错了什么 ?我定义了以下类:跨领域的Java Bean验证不验证JSF的字段

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对象进行验证以确保开始日期总是在结束日期之前)

回答

1

经过一番研究,我意识到对于这种交叉字段验证,使用JSR303 bean验证,类级别的验证是必需的。遗憾的是,直到JSF 2.3版本,这个选项不可用,因为它在这个post中声明。所以仅使用JSF是不可能的。但是可以在Omnifaces的帮助下完成。在Omnifaces showcase上可以找到很好的课程级别验证示例。应用该解决方案,我的任务是在形式与日历元素添加<o:validateBean value="#{pFSBean.dateRange}"/>简单:

<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将被调用。当然,这不是完美的解决方案,因为需要额外的工具,但没有它可惜是不可能的