2012-05-10 91 views
2

我一直在尋找一種方法,使表單驗證儘可能簡單和不顯眼,在Spring MVC 3中。我喜歡春天可以處理Bean驗證通過傳遞@Valid到我的方式模型(已使用驗證器註釋進行註釋)並使用result.hasErrors()方法。正確的形式驗證與Spring MVC 3 - 捕捉PersistenceException

我建立我的控制器操作是這樣的:

@RequestMapping(value = "/domainofexpertise", method = RequestMethod.PUT) 
public String addDomainOfExpertise(@ModelAttribute("domainOfExpertise") 
@Valid DomainOfExpertise domainOfExpertise, final BindingResult result) { 

    if (result.hasErrors()) { 
     return "/domainofexpertise/add"; 
    } else { 
     domainOfExpertiseService.save(domainOfExpertise); 
     return "redirect:/admin/domainofexpertise/list"; 
    } 
} 

這就像一個魅力的作品。數據庫異常(例如試圖用一個唯一的字段約束保存某些東西)仍然會通過。有沒有什麼辦法可以在後臺驗證過程中捕獲這些例外情況?這種驗證方式非常簡潔,所以我想避免在我的控制器中手動捕獲它們。

這方面的任何信息?

+0

控制器的驗證是爲了防止直到數據庫層的調用傳播,但爲什麼要在這一層處理數據庫異常。如果您在數據庫層遇到異常,應該傳播至控制器,並顯示錯誤或重定向到其他頁面。如果你在這裏做,我看到違反了分離的擔憂。只是我的想法。 – raddykrish

+0

所以我應該捕獲我的服務層的保存方法中的持久性異常?在做這件事情時,將異常返回給控制器的正確方法是什麼? – geoffreydv

+1

有幾種方法可以解釋你的異常,其中之一就像下面Luciano提到的那樣定義了一個通用的ExceptionHandler,另一個方法是捕獲持久性異常並重新引發應用程序特定的運行時異常並聲明類似於泛型的頁面Web.xml中的「技術難點」來處理這個問題,另一個是捕獲並重新拋出應用程序特定的檢查異常,並在控制器層適當地處理並向用戶顯示解釋的消息(這不是我的整個調用方法堆棧應該拋出聲明)。 – raddykrish

回答

3

這裏是我用來將PersistentExceptions轉換爲友好的消息的例子。這是Controller中的一種方法。這會爲你工作嗎?

/** 
* Shows a friendly message instead of the exception stack trace. 
* @param pe exception. 
* @return the exception message. 
*/ 
@ExceptionHandler(PersistenceException.class) 
@ResponseBody 
@ResponseStatus(HttpStatus.BAD_REQUEST) 
public String handlePersistenceException(final PersistenceException pe) { 
    String returnMessage; 
    if (pe.getCause() 
      instanceof ConstraintViolationException) { 
     ConstraintViolationException cve = 
       (ConstraintViolationException) pe.getCause(); 
     ConstraintViolation<?> cv = 
       cve.getConstraintViolations().iterator().next(); 
     returnMessage = cv.getMessage(); 
    } else { 
     returnMessage = pe.getLocalizedMessage(); 
    } 
    if (pe instanceof EntityExistsException) { 
     returnMessage = messages.getMessage("user.alreadyexists"); 
    } 
    return returnMessage; 
}