2011-08-27 60 views
6

我在我的應用程序中使用spring和Hibernate,有一種情況下,我插入相同的記錄morethan一次,因此,應用程序正確拋出約束異常,因爲我在db列之一應用唯一約束。一切都很好。自定義異常消息與Spring框架

但我必須顯示一些自定義消息,如「記錄已存在」,而不是顯示休眠異常。

我該如何處理Spring框架。

任何提示或例子非常感謝。

問候,

拉朱

回答

6

當然可以例外控制器:

@ExceptionHandler(Exception.class) 
     public ModelAndView handleMyException(Exception exception) { 
     ModelAndView mv = new ModelAndView("error"); 
     mv.addObject("message"."record already exists"); 
     return mv; 
       } 

因爲你可以捕獲異常的任何tpe只需將它作爲參數插入到@ExceptionHandler

希望它有幫助。

+0

+1,謝謝! – Gabber

0

你可以趕上彈簧拋出的異常/休眠並拋出自己的異常之一,其將持有的「記錄已經存在」的消息,你甚至可以查找一個本地化從資源包的消息並顯示您的演示文稿層對這個消息(例如JSP)

+0

即使我想通過擴展異常相同,我將創建一個exception.But我如何顯示相同的消息在春季presetation層。 – Raj

+0

當用戶嘗試添加重複記錄時,您可以從hibernate中捕獲異常,然後在您的服務層(即您調用後端邏輯的位置)嘗試插入記錄,並捕獲異常,然後轉發到錯誤頁面,這樣的事情 – eon

2

我面臨同樣的問題,但在我的情況下,可以複製一個或幾個字段(用戶名或電子郵件)。因此,org.hibernate.exception.ConstraintViolationException不足以說明用戶名或電子郵件是否導致拋出此異常,並導致顯示何種消息。

我剛纔看了danny.lesnik's answer,但它不是很好,因爲它只是重定向到「專用」頁面。假設你只是簡單地重定向到頁面上的用戶,就可以避免創建一個新的頁面。不過,我認爲你已經有一個Spring validator做一些形式驗證工作。這就是爲什麼在我的情況下,我決定只是在同一個地方(在驗證器)做我的領域(用戶名和電子郵件)重複檢查。看起來像一個更合適的,一致的(位於驗證的其餘部分)和更清潔的解決方案。

下面是一些代碼來說明:

我的控制器

@Controller 
public class WebController { 

    @Autowired 
    private UserServiceImpl userService; 

    @Autowired 
    private CustomUserDetailsValidator customUserDetailsValidator; 

    ... 
    @RequestMapping(value = "/login/create-account", method = RequestMethod.POST) 
    public String createAccount(@ModelAttribute("user") CustomUserDetails user, BindingResult result, Model model, SessionStatus status) { 

     customUserDetailsValidator.validate(user, result); 

     if(result.hasErrors()){ 
      model.addAttribute("user", user); 

      // Print the errors to the console - FIXME: log error instead 
       System.out.println("Validation errors:"); 
       for (FieldError error : result.getFieldErrors()) { 
        System.out.println(error.getField() + " - " + error.getDefaultMessage()); 
      } 

      return "login/create-account"; 
     } 
     else{ 
      userService.registerUser(user);    
      return "redirect:/login/create-account-success"; 
     } 
    } 
    ... 
} 

我的驗證

public class CustomUserDetailsValidator implements Validator { 

    @Autowired 
    private UserServiceImpl userService; 
    ... 

    @Override 
    public void validate(Object target, Errors errors) { 

     // some simple validations 

     // and here some complex validation (is username or email used duplicated?) 
     if(errors.getAllErrors().size() == 0){ 

      if (userService.doesUsernameAlreadyExist(user.getUsername())) 
       errors.rejectValue(usernameFieldName, "duplicate.username","username already exists"); 

      if (userService.doesEmailAlreadyExist(user.getEmail())) 
       errors.rejectValue(emailFieldName, "duplicate.email","email already exists"); 

     } 
    } 
} 

我不能確定這是做到這一點的最好辦法,但認爲我的解決辦法允許更多的擴展(你可以添加任何其他約束的各種檢查)。

希望它可以幫助其他人,在這個解決方案中獲得更多的開發者的想法也很有趣。