如何在Java中验证时间戳记间隔?

时间:2019-10-10 18:09:28

标签: java validation

我想为时间戳范围检查创建一个新的注释,但是它没有用。我试图用javax.validation创建它,需要检查validFrom和validTo间隔。

1 个答案:

答案 0 :(得分:1)

创建一个继承此接口的对象。

public interface EpochInterval {
    Long getStartTime();
    Long getEndTime();
}

然后创建您的验证器

@Component
public class PeriodConstraintValidator implements ConstraintValidator<PeriodConstraint, EpochInterval> {

    private final TimeZoneUtil timeZoneUtil;
    private Set<ChronoUnit> supportedUnits;

    private long amount;
    private ChronoUnit units;

    public PeriodConstraintValidator(TimeZoneUtil timeZoneUtil) {
        this.timeZoneUtil = timeZoneUtil;
        supportedUnits = new HashSet<>(5);
        supportedUnits.add(ChronoUnit.DAYS);
        supportedUnits.add(ChronoUnit.WEEKS);
        supportedUnits.add(ChronoUnit.MONTHS);
        supportedUnits.add(ChronoUnit.YEARS);
    }

    @Override public void initialize(PeriodConstraint constraintAnnotation) {
        ChronoUnit units = constraintAnnotation.units();
        if (!supportedUnits.contains(units))
            throw new IllegalArgumentException("Unit " + this.units.name() + " is not supported");

        this.amount = constraintAnnotation.amount();
        this.units = units;
    }

    @Override public boolean isValid(EpochInterval interval, ConstraintValidatorContext context) {

        Instant start = Instant.ofEpochSecond(interval.getStartTime());
        Instant end = Instant.ofEpochSecond(interval.getEndTime());

        Period between = Period.between(
                start.atZone(timeZoneUtil.getUTC()).toLocalDate(),
                end.atZone(timeZoneUtil.getUTC()).toLocalDate());

        // Custom checking, delete if not necessary
        if (between.getDays() <= 0) {
            context.disableDefaultConstraintViolation();
            context
                    .buildConstraintViolationWithTemplate("Period should be at least one day long")
                    .addPropertyNode("startTime")
                    .addConstraintViolation();
            context
                    .buildConstraintViolationWithTemplate("Period should be at least one day long")
                    .addPropertyNode("endTime")
                    .addConstraintViolation();
            return false;
        }

        if (between.get(units) < amount) {
            String unit = units.toString();
            String msg = "Given duration is less than a " + unit.substring(0, unit.length() - 1).toLowerCase();
            context.disableDefaultConstraintViolation();
            context
                    .buildConstraintViolationWithTemplate(msg)
                    .addPropertyNode("startTime")
                    .addConstraintViolation();
            context
                    .buildConstraintViolationWithTemplate(msg)
                    .addPropertyNode("endTime")
                    .addConstraintViolation();
            return false;
        }

        return true;
    }
}

然后为时间间隔创建一个注释:

@Constraint(validatedBy = PeriodConstraintValidator.class)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface PeriodConstraint {
    String message() default "Invalid interval";
    Class<?>[] groups() default { };
    Class<? extends Payload>[] payload() default { };
    ChronoUnit units();
    long amount();
}

然后注释您的对象,该对象必须继承上述接口:

@PeriodConstraint(units = ChronoUnit.DAYS, amount = 7)
public class YourClazz implements EpochInteval {
    private Long startTime;
    private Long endTime;    

    // Getters and setters are omitted for brevity
}