2015-01-09 50 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的更多信息,什麼是可能的。