在Spring中使用验证将ZonedDateTime字段限制为毫秒时的3位数

问题描述 投票:0回答:2

我在要验证的Spring MVC请求中有一个输入DTO,特别是ZonedDateTime字段最多应该包含毫秒级的3位数,即它不能是完整的纳秒级精度。除此之外,输入请求应遵循ISO日期时间格式。我可以使字段成为一个字符串,然后用正则表达式限制它,但我更喜欢将它保留为ZonedDateTime,所以我不需要再次解析它。

该对象如下所示:

@Data
public class MeasurementDTO {

    private ZonedDateTime date;
    @Digits(integer = 20, fraction = 8) private BigDecimal value;

}

这是一个嵌套的DTO,其中父对象作为带有@RequestBody注释的@Valid进入。

我试过@JsonFormat,但我似乎无法限制毫秒级。有没有办法做到这一点,或者我应该自己解析它作为一个字符串然后处理它?或者甚至只是将它留在ZonedDateTime,然后检查纳秒组件,看看它是否在自定义验证器中?

感谢蒂姆的回答,我记得Java Dates没有比millis更精确,所以我更新了问题,使用ZonedDateTimes,它具有高达纳秒的精度。我确实希望能够在用户尝试传递更多精度时向用户发出警告,如果使用日期,则此信息将被吞下。

java spring validation hibernate-validator
2个回答
1
投票

您可能不认为这是一个完整的答案,但java.util.Date只存储精度高达毫秒,而不是超过这个。请参阅Jon Skeet的answer here,或阅读source code for CalendarDate,它显示它没有超过毫秒的存储空间。

因此,使用Hibernate验证将Date限制为毫秒级精度是没有意义的,因为类型本身已经具有此限制。


0
投票

我用自定义验证器这么做了。我仍然欢迎以更简洁的方式做到这一点的答案。

这是我的解决方案:

我添加了一个注释@ValidMeasurementInput

@Documented
@Constraint(validatedBy = MeasurementValidator.class)
@Target({TYPE, FIELD, ANNOTATION_TYPE})
@Retention(RUNTIME)
public @interface ValidMeasurementInput {

    String message() default "Invalid measurement input";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

并实现了自定义验证器

public class MeasurementValidator implements ConstraintValidator<ValidMeasurementInput, MetricsDTO> {

    @Override
    public boolean isValid(MetricsDTO metricsDTO, ConstraintValidatorContext context) {
        ...
    }
}

在这个类中的某些其他验证中的代码是这个代码:

   int nano = measurementDTO.getDate().getNano();
   int remainderAfterMillis = nano % 1000000;
   if (remainderAfterMillis != 0)
       valid = false;

当然,我将@ValidMeasurementInput添加到了我的DTO。

© www.soinside.com 2019 - 2024. All rights reserved.