在日常開發中常常會出現接口參數中有開始時間和結束時間兩個屬性,需要校驗兩個時間的大小關係,但JSR-303並未給出這樣的註解,但是給出了ConstraintValidator這個接口,提供用戶的自定義校驗。下面開始開始時間和結束時間校驗的註解。
1 時間校驗註解
這個註解只能應用於類上,通過startTime和endTime方法指定被註解的類的開始時間和結束時間的屬性名。
@Target({ElementType.TYPE})
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {TimeValidate.class})
public @interface TimeValidate {
String message() default "開始時間不能大於結束時間";
String startTime() default "startTime";
String endTime() default "endTime";
boolean required() default true;
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
2 時間校驗的實現類TimeValidate
@Slf4j
public class TimeLimitValidate implements ConstraintValidator<TimeLimit, Object> {
private TimeLimit timeLimit;
@Override
public void initialize(TimeLimit constraintAnnotation) {
this.timeLimit = constraintAnnotation;
}
@Override
public boolean isValid(Object object, ConstraintValidatorContext constraintValidatorContext) {
Object startTime = getObjectPropertyValue(object, timeLimit.startTime());
Object endTime = getObjectPropertyValue(object, timeLimit.endTime());
if(null == startTime || null == endTime || !startTime.getClass().equals(endTime.getClass())) {
return true;
}
if(startTime instanceof Long && (Long)startTime > (Long) endTime) {
return false;
}
if(startTime instanceof Date && ((Date) startTime).getTime() > ((Date)endTime).getTime()) {
return false;
}
return true;
}
/**
* 從Object中獲取指定的屬性的值
* @param object
* @param paramName
* @return
* @throws NoSuchFieldException
* @throws IllegalAccessException
*/
private Object getObjectPropertyValue (Object object, String paramName) {
Field field = null;
try {
field = object.getClass().getDeclaredField(paramName);
field.setAccessible(true);
return field.get(object);
} catch (Exception e) {
log.info("===異常信息 e = ", e);
}
return null;
}
}
通過反射獲取類中指定的屬性值,在Spring中提供了BeanWrapper接口,可以獲取到Object的指定屬性的值。這裏可以進一步優化。