【问题标题】:How to process hibernate exception using Spring @ControllerAdvice and problem-spring-web如何使用 Spring @ControllerAdvice 和 question-spring-web 处理休眠异常
【发布时间】:2020-12-09 13:33:18
【问题描述】:

您好 Stackoverflow 专家,

如何处理 org.hibernate.exception.ConstraintViolationException(以及所有其他休眠异常)和 RuntimeException 以将以下 json 返回到前端?

  {
    "timestamp": "2020-08-18T21:03:36.174Z",
    "code": "CODE_20500",
    "status": 500,
    "details": "An internal error occurred."
  }

实际上我已经声明了我的 ControllerDevice 并按照 https://www.baeldung.com/problem-spring-web 的 Baeldung 指南的步骤进行操作:

@ControllerAdvice
public class MyErrorHandlingControllerAdvice implements ProblemHandling {
}

我还在“application.properties”文件中设置了这些属性

  spring.resources.add-mappings=false
  spring.mvc.throw-exception-if-no-handler-found=true
  servlet.http.encoding.force=true

但是,当尝试将重复的主键保存在数据库中时,我收到以下消息:

{
  "timestamp": "2020-08-20T08:44:11.342+02:00",
  "status": 400,
  "detail": "could not execute statement; SQL [n/a]; constraint [uq_mykatalog_name]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement"
}

出于安全原因,我们不能将数据库字段公开。

我正在使用这些库版本:

springboot 版本 = 2.3.3.RELEASE

实现“org.zalando:problem-spring-web:0.23.0”

请帮忙! 谢谢。

【问题讨论】:

    标签: java spring-boot exception spring-data-jpa


    【解决方案1】:

    这是因为问题库默认会打印出异常类中包含的异常信息。

    你可以做的是:

    1. 将对数据库的调用包装在 try/catch 子句中(以捕获 Hibernate 异常)并重新引发自定义异常以隐藏不安全的详细信息。
    2. 为休眠异常实现ExceptionHandler,并重新抛出将隐藏详细信息的自定义异常 - 请参阅此处的指南https://www.baeldung.com/exception-handling-for-rest-with-spring 解决方案 1

    【讨论】:

    • 谢谢,但我不想用 try/catch 包装 1000 行代码或重新抛出任何东西。任何异常都必须由@ControllerAdvice 和库问题 Spring Web 集中处理。
    • 我可以理解——这就是为什么我提出可以集中处理该问题的第二种解决方案的原因——您可能可以捕获org.hibernate.HibernateException 来处理所有休眠异常。但是在这种情况下,您需要重新抛出自定义异常 - 如果您不想这样做,那么我们需要等待另一个答案
    【解决方案2】:

    解决方案:

    1. 创建一个扩展 AbstractThrowableProblem 的类“CustomException”并将您的自定义字段放在那里。对我来说是“代码”字段。

    2. 将以下代码放入您的 ControllerDevice:

    @ControllerAdvice
    public class MyErrorHandlingControllerAdvice implements ProblemHandling {
    
        @ExceptionHandler({RuntimeException.class})
        @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
        @ResponseBody CustomException onUnexpectedRuntimeException(RuntimeException e) {
            return new CustomException("CODE_20500","An Internal error occurred.", INTERNAL_SERVER_ERROR);
        }
    }
    

    它将处理任何扩展 RuntimeException 的异常,包括 org.hibernate.exception.ConstraintViolationException

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-06-04
      • 1970-01-01
      • 2017-11-23
      • 2019-11-29
      • 1970-01-01
      • 1970-01-01
      • 2016-03-25
      相关资源
      最近更新 更多