2015-01-09 48 views
1

我正在开发一个Web应用程序,并试图确定在数据持久存在之前验证数据的最佳做法。使用DAO进行数据验证的模式

我现在有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的进入时,我确认在网络上的数据甚至在尝试使用DAO之前。

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

我在问,因为我发现我维持2组验证。

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

一旦我把它提交给DAO,我期待操作成功完成,因为我已经'审查'了Web层中的数据。例如,DAO级别的验证中发生的任何异常都会用作记录的文本,然后发送500错误响应,但例外情况下的基础消息不是我向用户显示的内容。

我真的很想只有1个地方进行验证维护,因此我不必在2个地方进行更改,但我真的只是想找出建立的最佳实践。

回答

0

我会把它交给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,更新前和删除前)自动执行。

手动验证可以做这样的:

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

JPA Entity tutorialBean validation tutorial的更多信息,什么是可能的。