使用@Future,@ NotNull等默认的BeanValidation注释,我的JSF表单中的字段突出显示,默认显示验证错误文本。但是,当我尝试针对所选房间的预订列表验证RoomReservation并从/到日期中选择时,我会在堆栈跟踪中打印异常。我假设异常是说保留没有通过验证而不是验证过程失败,并且此异常无法通过任何处理ValidationExceptions进行处理并被重新抛出。
作为一个workarround我在我的控制器中使用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}'}]
然后是堆栈跟踪。