Spring mvc 使用Spring框架定制异常消息

Spring mvc 使用Spring框架定制异常消息,spring-mvc,exception-handling,Spring Mvc,Exception Handling,我在我的应用程序中使用spring和Hibernate,有一种情况是我多次插入相同的记录,所以应用程序正确地抛出约束异常,因为我在其中一个db列中应用了唯一约束。到目前为止一切正常 但是我必须显示一些自定义消息,比如“记录已经存在”,而不是显示Hibernate异常 如何使用Spring框架 非常感谢任何提示或示例 问候, Raju您可以捕获spring/hibernate引发的异常,并引发一个您自己的异常,该异常将保存“记录已存在”消息,您甚至可以从资源包中查找本地化消息,并在您的表示层(例如

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

但是我必须显示一些自定义消息,比如“记录已经存在”,而不是显示Hibernate异常

如何使用Spring框架

非常感谢任何提示或示例

问候,


Raju

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

是的,您可以在控制器中显示异常:

  @ExceptionHandler(Exception.class)
      public ModelAndView handleMyException(Exception  exception) {
         ModelAndView mv = new ModelAndView("error");
         mv.addObject("message"."record already exists");
         return mv;
              } 
当然,您可以捕获任何异常的tpe,只需将其作为参数插入到
@ExceptionHandler


希望有帮助。

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

我只是看了一下,但它不是很好,因为它只是重定向到一个“专用”页面。假设您只是重定向到用户所在的页面,则可以避免创建新页面。不过,我假设您已经有了一个进行表单验证工作的团队。这就是为什么在我的例子中,我决定只在同一个地方(在验证器中)进行字段(用户名和电子邮件)重复检查的原因。似乎是一种更合适、更一致(与验证的其余部分一致)和更清洁的解决方案

下面是一些代码来说明:

我的控制器

@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");

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


希望它能帮助其他人,也希望能让更多开发人员对这个解决方案有更多的想法。

即使我通过扩展异常也会有同样的想法,我也会创建一个异常。但我如何在Spring预设层中显示相同的消息。当用户尝试添加重复记录时,您可以从hibernate捕获异常,然后在您的服务层(即您调用后端逻辑的地方),您将尝试插入记录,捕获异常,然后转发到错误页,类似这样的内容