使用Spring框架的自定义异常消息

时间:2011-08-27 22:29:57

标签: spring-mvc exception-handling

我在我的应用程序中使用spring和Hibernate,有一个场景我插入相同的记录超过一次,因此应用程序正确抛出Constraint异常,因为我在其中一个db列中应用了Unique约束。所以一切都很好。< / p>

但是我必须显示一些自定义消息,例如“record already exists”,而不是显示Hibernate异常。

我如何处理Spring框架。

非常感谢任何提示或示例。

此致

Raju

3 个答案:

答案 0 :(得分:6)

是的,您可以在控制器中例外:

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

原因是你可以捕获任何异常,只需将其作为参数插入@ExceptionHandler

希望它有所帮助。

答案 1 :(得分:2)

我面临同样的问题,但在我的情况下,可以复制一个或多个字段(用户名或电子邮件)。因此,org.hibernate.exception.ConstraintViolationException不够具体,无法说明用户名或电子邮件是否会引发此异常以及由此显示的消息。

我只是看了danny.lesnik's answer,但它并不好,因为它只是重定向到“专用”页面。假设您只是重定向到用户打开的页面,将避免创建您要说的新页面。但是我假设你已经有Spring validator做了一些表单验证工作。这就是为什么在我的情况下我决定在同一个地方(在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");

        }
    }
}

我不确定这是否是执行此操作的最佳方法,但我认为我的解决方案允许更多扩展(您可以对任何其他约束添加各种检查)。

希望它可以帮助其他人,让更多开发人员对这个解决方案有所了解也很有趣。

答案 2 :(得分:0)

你可以捕获spring / hibernate引发的异常并抛出一个你自己的异常,这些异常将保存'record already exists'消息,你甚至可以从资源包中查找本地化消息并在你的演示文稿中显示此消息层(例如jsp)