2016-10-25 93 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將被調用。當然,這不是完美的解決方案,因爲需要額外的工具,但沒有它可惜是不可能的