使用@Future、@NotNull 等默认的 BeanValidation 注释,我可以在我的 JSF 表单中突出显示字段,并默认显示验证错误文本。但是,当我尝试根据所选房间的预订列表验证 RoomReservation 并选择从/到日期时,我会在堆栈跟踪中打印出异常。我假设异常是说保留没有通过验证,而不是验证过程失败,并且这个异常不能被任何处理 ValidationExceptions 并被重新抛出。
作为一种解决方法,我在控制器中使用 try catch 块,如果它被抛出,则显示占位符错误消息,但我想避免这种情况。
是否可以让 JSF 处理这个异常并更新表单?
这是我的 RoomReservation 课程:
@Entity
@RoomAvailable
public class RoomReservation{
//fields, getters, setters follow
}
为了验证房间预订,我实施了班级级别的注释:
@Constraint(validatedBy = RoomAvailableValidator.class)
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface RoomAvailable{
String message() default "{invalid.roomReserved}";
Class<?>[] groups() default {};
boolean optional() default true;
Class<? extends Payload>[] payload() default {};
}
这是 RoomAvailableValidator 的 isValid 方法:
@Override
public boolean isValid(RoomReservation reservation, ConstraintValidatorContext context) {
boolean isValid = evaluate(reservation);
if(!isValid){
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate( "{invalid.roomReserved}" )
.addNode( "dateFrom" )
.addConstraintViolation();
}
return isValid;
}
我对这种方法的期望是将 dateFrom 字段“标记”为无效,因此它在表单中突出显示并带有验证错误消息。使用字段级注释时,我默认会得到这种行为。但是,我得到的只是这个警告。
25.7.2013 18:50:27 com.sun.faces.lifecycle.InvokeApplicationPhase execute
WARNING: #{roomController.saveRoomReservation}:
javax.validation.ConstraintViolationException: Validation failed for classes
[sk.bantip.hotel.server.model.entity.venues.Session] during update time for groups
[javax.validation.groups.Default, ]
List of constraint violations:[
ConstraintViolationImpl{interpolatedMessage='{invalid.roomReserved}',
propertyPath=dateFrom, rootBeanClass=class
sk.bantip.hotel.server.model.entity.venues.Session,
messageTemplate='{invalid.venueReserved}'}]
javax.faces.FacesException: #{roomController.saveRoomReservation}:
javax.validation.ConstraintViolationException: Validation failed for classes
[package.RoomReservation] during update time for groups
[javax.validation.groups.Default, ]
List of constraint violations:[
ConstraintViolationImpl{interpolatedMessage='{invalid.roomReserved}',
propertyPath=dateFrom, rootBeanClass=class package.RoomReservation,
messageTemplate='{invalid.roomReserved}'}]
其次是堆栈跟踪。