向实体类提供 Java 时钟以进行 Spring 验证

Supplying Java Clock to Entity Class for Spring Validation

提问人:pbuchheit 提问时间:10/11/2023 更新时间:10/11/2023 访问量:36

问:

我正在开发一个spring-boot应用程序。我有一个名为 Message 的实体类,我想使用 Spring 验证来验证它。我需要验证的字段之一是 LocalDateTime,它不得超过当前日期的 6 天。我的实体类如下所示:

@Entity
@EntityListeners(AuditingEntityListener.class)
public class Message implements Validator {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id", length = 100, nullable = false, unique = true)
    private long id;

    @Column(name = "start", length = 20, nullable = true)
    private LocalDateTime start;

    public Message() {}

    @Override
    public boolean supports(@NotNull Class<?> clazz) {
        return Message.class.equals(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {
        Message m = (Message) target;

        if(m.getStart() != null && m.getStart().isBefore(LocalDateTime.now(clock).minusDays(6)))
        {
            errors.rejectValue("start", "beforeMinStart");
        }
    }
}

我遇到的问题是我希望能够为验证提供时钟,以便我可以使用固定的日期时间进行测试。我不能简单地使用构造函数;消息可能来自数据库查找。我更喜欢使用依赖注入,但我不确定它如何与 Entity 类一起使用。有没有一些我没有看到的方法可以做到这一点?

Java Spring DateTime 验证 实体

评论

0赞 Basil Bourque 10/11/2023
顺便说一句,请注意这是模棱两可的,没有时区或与UTC的偏移量的概念。该方法使用JVM的当前默认时区来确定日期和时间。该时间,甚至该日期,可能会因当前默认时区而异。对于任何给定的时刻,日期在全球范围内因时区而异,东京为“明天”,而俄亥俄州托莱多为“昨天”。我怀疑你的情况真的需要一个 or 而不是 .LocalDateTimenowInstantZonedDateTimeLocalDateTime

答:

5赞 Jorn 10/11/2023 #1

将 Entity 类和 Validator 类分开:

@Entity
@EntityListeners(AuditingEntityListener.class)
public class Message {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id", length = 100, nullable = false, unique = true)
    private long id;

    @Column(name = "start", length = 20, nullable = true)
    private LocalDateTime start;

    public Message() {}
}

public class MessageValidator implements Validator {
    @Autowired private Clock clock;

    @Override
    public boolean supports(@NotNull Class<?> clazz) {
        return Message.class.equals(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {
        Message m = (Message) target;

        if(m.getStart() != null && m.getStart().isBefore(LocalDateTime.now(clock).minusDays(6)))
        {
            errors.rejectValue("start", "beforeMinStart");
        }
    }
}

现在,您可以自动连接所需的任何依赖项。