【问题标题】:Patterns for Data validation when using a DAO使用 DAO 时的数据验证模式
【发布时间】:2015-03-08 04:42:24
【问题描述】:

我正在开发一个 Web 应用程序,并试图确定在数据被持久化之前验证数据的最佳实践。

我目前有 2 个 DAO 接口:

UserDAOInt - defines what operations a user can perform, throws data validation exceptions

UserDAOPersistenceInt - defines what operations a user can perform, throws jpa exceptions

我有相应的 DAO 接口实现:

UserDAOImpl - implements UserDAOInt, validates the data by making sure all data required is present, making sure that the entities being updated or deleted exist in the database. If there is an issue, an exception is thrown. If everything is ok, a call is made to the corresponding method in the classes UserDAOPersistenceInt implementation.

UserDAOPersistenceImpl - implements the UserDAOPersistenceInt. The only validation that occurs is checking for null objects returned by EntityManager calls, just in case they were removed between the time the validation occurred and the call to the method. Throws persistence related exceptions or Exception if a null object was returned by the EntityManager.

当数据来自 servlet 时,我会在 Web 层端验证数据,然后再尝试使用 DAO。

我的问题是,在 Web 层端验证数据并再次在 DAO 中验证数据是不好的做法吗?

我之所以问,是因为我发现我正在维护 2 组验证。

在 servlet 上进行的验证是对来自用户的数据进行验证,主要是在表单中。如果这里发生验证错误,我通常会使用验证错误的文本作为反馈给用户,例如,填写表单时需要 First Name。

一旦我进入 DAO,我希望操作能够成功完成,因为我已经“审查”了 Web 层中的数据。例如,在 DAO 级别的验证中发生的任何异常都用作记录的文本,然后发送 500 错误响应,但异常中的基础消息不是我向用户显示的内容。

我真的希望只有 1 个地方维护验证,这样我就不必在 2 个地方进行更改,但我真的只是想找出已建立的最佳实践是什么。

【问题讨论】:

    标签: java validation jakarta-ee jpa


    【解决方案1】:

    我会将其交给 bean 验证框架。它允许您在一个地方管理验证规则,作为 bean 的注释,如下所示:

    @Entity
    public class Contact implements Serializable {
        private static final long serialVersionUID = 1L;
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
        @NotNull
        protected String firstName;
        @NotNull
        protected String lastName;
        @Pattern(regexp="[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\."
            +"[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@"
            +"(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?",
                 message="{invalid.email}")
        protected String email;
        @Pattern(regexp="^\\(?(\\d{3})\\)?[- ]?(\\d{3})[- ]?(\\d{4})$",
                 message="{invalid.phonenumber}")
        protected String mobilePhone;
        @Pattern(regexp="^\\(?(\\d{3})\\)?[- ]?(\\d{3})[- ]?(\\d{4})$",
                 message="{invalid.phonenumber}")
        protected String homePhone;
        @Temporal(javax.persistence.TemporalType.DATE)
        @Past
        protected Date birthday;
    }
    

    验证将在 JPA 生命周期事件(PrePersist、PreUpdate 和 PreRemove)期间自动执行。

    手动验证可以这样完成:

    ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
    Validator validator = factory.getValidator();
    Set<ConstraintViolation<Contact>> errors = validator.validate(bean);
    

    请参阅JPA Entity tutorialBean validation tutorial 了解更多信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-11
      • 2014-12-26
      • 2011-09-08
      • 2013-02-09
      • 2010-09-07
      • 1970-01-01
      • 1970-01-01
      • 2022-01-25
      相关资源
      最近更新 更多