Spring Boot 异常处理数据库错误的自定义异常?

Posted

技术标签:

【中文标题】Spring Boot 异常处理数据库错误的自定义异常?【英文标题】:Spring Boot Exception Handling custom Exceptions for Database Errors? 【发布时间】:2022-01-12 18:02:12 【问题描述】:

我为运行时可能发生的各种错误创建了多个自定义异常。为此,我使用了 @ControllerAdvice 注释和全局错误处理程序(如此处所述:Spring Boot Exception Handling. 我还在数据库级别实现了约束(如果这很重要,它是一个 SQL Server 数据库),并且我有一个表,它有两个不同的约束,在插入数据时可能会抛出这些约束。

我现在想做的是在 Spring Boot 中为数据库级别的每个约束实现自定义异常,这样我就可以向用户反馈他试图发送到我的后端的数据集有什么问题。这可能吗?如果是,怎么办?

【问题讨论】:

【参考方案1】:

Spring 使用 DataAccessException 层次结构,它让我们在不知道数据库细节的情况下处理异常。

您可以在控制器建议中捕获它们并应用您想要的逻辑。

更新:

尝试将此行放在您的控制器建议中

 @ExceptionHandler(DataAccessException.class)
 @ResponseStatus(HttpStatus.BAD_REQUEST)
 @ResponseBody
 public RestApiError handle(DataAccessException e) 
   // Add your logic here 
 

【讨论】:

嘿,感谢您的回答,我已经实现了控制器建议类,到目前为止它对于应用程序级别的错误运行良好。我现在要做的是根据数据库响应处理异常。我有一个带有列 ID、a、b、c 和 a+b 的表,b+c 各有一个唯一的约束。我希望能够告诉用户他的数据破坏了哪些约束,以便他可以修复它。【参考方案2】:

正如@Jaume 提到的 - Spring 将异常包装在它自己的层次结构中。但是,它实际上包装了由数据库驱动程序创建的原始异常,如果您使用的是 JPA/Hibernate,则异常也被包装在两者之间。该原始异常包含您感兴趣的数据。例如,如果我有一个实体Book,在字段name 上有一个唯一约束,并且我尝试创建两本具有相同名称的书籍,那么如果我使用HSQLDB in-内存数据库然后我得到以下异常层次结构(第一个是顶部的那个。

org.springframework.dao.DataIntegrityViolationException ( from Spring)
org.hibernate.exception.ConstraintViolationException ( from Hibernate)
java.sql.SQLIntegrityConstraintViolationException ( from hsqldb driver)

异常的最内层或根本原因包含有关约束违反和表的信息。

java.sql.SQLIntegrityConstraintViolationException: integrity constraint violation: unique constraint or index violation; UK_WUGRYET8MF6OI28N00X2EOC4 table: BOOK

您还可以获得由 JDBC 定义的 SQLStateVendorCode 字段,它们可以提供有关 SQL 异常的信息。您可以使用here提供的实用程序来提取信息

您可以使用下面的代码循环查找异常的根本原因。

public static Throwable getRootException(Throwable exception)
         Throwable rootException=exception;
         while(rootException.getCause()!=null)
          rootException = rootException.getCause();
         
         return rootException;
         

因此,本质上您需要在异常处理程序中获取异常的根本原因,并为您的客户构建适当的响应。

【讨论】:

以上是关于Spring Boot 异常处理数据库错误的自定义异常?的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 异常自定义处理 - 意外的 HTTP 状态

抛出异常时,Spring Boot 不显示自定义错误

缺少资源 bean:Spring Boot webflux 自定义全局异常处理程序

Spring Boot制作个人博客-框架搭建(异常处理)

处理 Spring Boot 资源服务器中的安全异常

Spring MVC(或 Spring Boot)。针对安全相关异常(例如 401 Unauthorized 或 403 Forbidden)的自定义 JSON 响应)