我有一个简单的spring boot REST应用程序 . 这是DTO的样子:
@Data
public class FooDto {
@Min(value = 0L)
@NotNull
private final String amount;
@ValidTimestamp
private final String timestamp;
}
我在 @ValidTimestamp
中有一些验证逻辑,检查时间戳格式是否有效 . 但问题是,我在这里放了 @ValidTimestamp
注释,整个DTO中的所有其他默认JSR验证都停止了 . 他们根本不开火 . 如果我注释掉 @ValidTimestamp
那么那些默认的JSR验证就会变为活动状态 . 我已经在互联网上查找但找不到任何解决方案 . 欣赏快速指针 .
这是验证器类:
public class TimestampValidator implements ConstraintValidator<ValidTimestamp, String> {
@Override
public void initialize(@NonNull final ValidTimestamp constraintAnnotation) {
constraintAnnotation.payload();
}
@Override
public boolean isValid(final String timestamp,
@NonNull final ConstraintValidatorContext constraintValidatorContext) {
try {
final Duration duration = Duration.between(Instant.parse(timestamp), Instant.now());
throwIfOldTimeStampProvided(duration);
throwIfFutureTimestampProvided(duration);
} catch (DateTimeParseException dateTimeParseException) {
return throwInvalidTimestampFormatException(dateTimeParseException);
}
return true;
}
private boolean throwInvalidTimestampFormatException(@NonNull final DateTimeParseException dateTimeParseException) {
log.error("failed to parse the timestamp, exception is : {}", dateTimeParseException);
throw new InvalidTimestampFormatException("invalid timestamp supplied via request");
}
private void throwIfOldTimeStampProvided(@NonNull final Duration duration) {
if (duration.toMillis() > ACTIVE_TRANSACTION_TIME_REFERENCE * 1000) {
throw new StaleTransactionException("Transaction time is more than a minute ago");
}
}
private void throwIfFutureTimestampProvided(@NonNull final Duration duration) {
if (duration.isNegative()) {
throw new FutureTransactionException("Transaction time is of future");
}
}
}
这是注释:
@Target({FIELD})
@Retention(RUNTIME)
@Constraint(validatedBy = {TimestampValidator.class})
public @interface ValidTimestamp {
String message() default "";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}