2013-07-07 35 views
2

我一直在閱讀Java EE 6+附帶的Bean驗證API,並瞭解驗證API的工作原理,但在我一直在閱讀的文檔中,所有的例子是單元測試,它不能幫助我理解執行驗證操作的地方。使用EJB進行Bean驗證

我正在開發一個三層架構系統。我想將驗證放在服務層,所以如果表示層不同(如Jax-RS,JSF等),我可以重用驗證代碼。但是我對如何實施上述操作感到困惑。這裏是我卡在哪裏:

我有我的模型中的不同實體進行交互的bean。例如,這是對用戶交互我的bean中的一個方法 - >

public User getUser(
      @Min(value = 0, message = "Must have a positive userId") int uid) 
      throws RetrievalNotFoundException { 

     try { 

      // I WANT TO VALIDATE UID HERE 

      // find User with provided uid 
      User foundUser = em.find(User.class, uid); 

      // IF the user is inactive 
      if (foundUser.getIsActive() == 0) { 
       // cannot find the content 
       throw new RetrievalNotFoundException(); 
      } 

      // close the entity manager 
      em.close(); 
      // return the user 
      return foundUser; 


    } 

下面是從Hibernate文檔的例子:

Car object = new Car("Morris"); 
Method method = Car.class.getMethod("drive", int.class); 
Object[] parameterValues = { 80 }; 
Set<ConstraintViolation<Car>> violations = executableValidator.validateParameters(
     object, 
     method, 
     parameterValues 
); 

assertEquals(1, violations.size()); 
Class<? extends Annotation> constraintType = violations.iterator() 
     .next() 
     .getConstraintDescriptor() 
     .getAnnotation() 
     .annotationType(); 
assertEquals(Max.class, constraintType); 

難道我真的要再次instatiate豆來訪問它的方法的getUser()?我很困惑。我的另一個問題是如果有人決定爲int容器溢出一個int來發生什麼情況?我將如何驗證?

非常感謝您的幫助, 我真的很感激。

回答

4

對您的問題的幾點意見。首先,Bean Validation確實是EE 6和EE 7的一部分。然而,EE 6僅包含Bean Validation 1.0,而EE 7包含Bean Validation 1.1。區別在於Bean Validation 1.0尚未包含方法驗證,這就是您在示例中顯示的內容。 Hibernate Validator從版本4開始包含Hibernate Validator特定的方法驗證API,但這不是標準的一部分,與Bean Validation 1.1和Hibernate Validator 5中指定的內容略有不同。

第二個註釋是關於需要的代碼執行方法驗證。 Bean驗證只提供了進行方法級驗證的機制。這是您在示例中提到的API。在大多數情況下,你需要某種攔截技術來利用它。例如,Java EE 7在默認情況下使用CDI攔截器進行方法驗證。它是標準的一部分。請參閱http://beanvalidation.org/1.1/spec/#integration-cdi。如果您想使用EE 6,您需要使用您選擇的技術編寫自己的攔截邏輯。

關於你的最後一個問題。我認爲一般來說溢出是不可檢測的。在這種情況下Bean Validation無能爲力。

+0

謝謝,那裏有很多有用的信息。其實我正在使用Java EE 7和glassfish 4.0運行時環境。我認爲那麼方法級別的驗證就像你說的那樣默認完成了。 我想我應該編寫自己的驗證器,然後爲具有更長參數列表的方法編寫內聯函數,以便不內聯所有參數約束。 感謝您的幫助! –

+1

正確,Glassfish 4的EE7根據我提到的spec部分啓用了方法驗證。關於自定義約束,您可以確定創建自己的約束,但我不明白這是如何減少註釋量的。除非你想將多個約束合併成一個單一的組合約束。這當然會減少註釋在參數上的位置。 – Hardy