【问题标题】:Custom Exception Messages with Spring framework使用 Spring 框架自定义异常消息
【发布时间】:2011-08-27 22:29:57
【问题描述】:

我在我的应用程序中使用 spring 和 Hibernate,有一种情况是我多次插入相同的记录,因此应用程序正确抛出约束异常,因为我在其中一个 db 列中应用了唯一约束。到目前为止一切都很好。

但我必须显示一些自定义消息,例如“记录已存在”,而不是显示 Hibernate Exception。

如何使用 Spring 框架。

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

问候,

拉朱

【问题讨论】:

    标签: spring-mvc exception-handling


    【解决方案1】:

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

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

    当然,您可以捕获任何异常,只需将其作为参数插入@ExceptionHandler

    希望对你有帮助。

    【讨论】:

      【解决方案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");
      
              }
          }
      }
      

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

      希望它可以帮助其他人,并且让更多开发人员对这个解决方案产生想法也很有趣。

      【讨论】:

        【解决方案3】:

        您可以捕获 spring/hibernate 引发的异常并引发您自己的异常之一,该异常将包含“记录已存在”消息,您甚至可以从资源包中查找本地化消息并在演示文稿中显示此消息层(例如jsp)

        【讨论】:

        • 即使我通过扩展异常的想法相同,我也会创建一个异常。但是我如何在 Spring 预设层中显示相同的消息。
        • 当用户尝试添加重复记录时,您可以从休眠中捕获异常,然后在您的服务层(即您调用后端逻辑的地方)您将尝试插入记录,并捕获异常然后转发到错误页面,类似的东西
        猜你喜欢
        • 1970-01-01
        • 2020-05-26
        • 2014-09-28
        • 2013-06-30
        • 2015-11-04
        • 2012-01-17
        • 1970-01-01
        • 1970-01-01
        • 2017-02-20
        相关资源
        最近更新 更多