【问题标题】:ControllerAdvice conditionally handle exceptionControllerAdvice 有条件地处理异常
【发布时间】:2020-12-02 05:46:56
【问题描述】:

我有一个控制器建议来处理我的 REST 控制器中的异常行为,我遇到了一种情况,我必须有条件地处理具有特定消息(重复键的消息)的 SQLIntegrityConstraintViolationException,返回 409 ,让其他的由默认处理程序处理(返回500 错误代码)。

我正在考虑两种可能的方法来实现这一目标:

  1. 根据我的情况在 else 分支上抛出一个新的裸机 Exception,因此处理由 Spring 完成。
  2. 显式调用通用异常处理程序(例如从我的 else 分支内部调用 return handleGeneralException(exception))。

我有一种“正确”的方式可以将我的ControllerAdvice 中的一小部分异常传递给另一个处理程序,而不是“原始”处理程序?

编辑 1: 我想在我的 ControllerAdvice 中做这样的事情:

if (exception.getMessage.contains("something")) {
    // handle exception
} else {
    // pass to other handler
}

【问题讨论】:

    标签: java spring-boot rest exception controller-advice


    【解决方案1】:

    有一个自定义异常类,然后当您抛出 SQLIntegrityConstraintViolationException 时,将其包装在您的自定义异常类中,其中包含您希望在控制器建议中访问的任何附加字段。处理控制器建议类中的自定义异常。

    @ControllerAdvice
    public class CustomExceptionHandler {
    
        @ExceptionHandler(YourCustomException.class)
        public final ResponseEntity<ExceptionResponse> handleNotFoundException(YourCustomExceptionex,
                WebRequest request) {
            ExceptionResponse exceptionResponse = new ExceptionResponse(new Date(), ex.getMessage(),
                    request.getDescription(false), HttpStatus.NOT_ACCEPTABLE.getReasonPhrase());
            return new ResponseEntity<>(exceptionResponse, HttpStatus.CONFLICT);
        }
    
    }
    

    虽然在代码中使用 try catch 块来处理此异常,但如果您使用 Spring Data JPA,请确保处理 DataIntegrityViolationException 而不是 SQLIntegrityConstraintViolationException。因此,如果您使用的是 Spring Data Jpa,那么:

    try {
        anyRepository.save(new YourModel(..));
    } catch (DataIntegrityViolationException e) {
        System.out.println("history already exist");in res
        throw New YourCustomException("additional msg if you need it ", e);
    }
    

    【讨论】:

    • 问题是这是一个运行时异常——我可以在哪里处理和包装它?有在控制器的建议?我的意思是,我从来没有在我的代码中处理它
    • 为您的代码创建一个 try catch 块,并在 catch 块句柄 SQLIntegrityConstraintViolationException 中重新抛出它作为您的自定义异常类。
    • 我的问题是我应该在哪里有那个 try-catch 块。请看我的编辑
    • @AvramPop 尝试捕获将在运行时抛出此异常的代码块。
    【解决方案2】:

    以下代码将在ControllerAdbvice中捕获异常SQLIntegrityConstraintViolationException的错误信息,无需在代码中处理

    @ControllerAdvice
    public class CustomGlobalExceptionHandler extends ResponseEntityExceptionHandler {
    @ExceptionHandler(value = DataIntegrityViolationException.class)
    public ResponseEntity<ExceptionResponse> dataIntegrityViolationExceptionHandler(Exception ex) {
    ExceptionResponse response = new ExceptionResponse();
        Throwable throwable = ex.getCause();
        while (throwable != null) {
            if (throwable instanceof SQLIntegrityConstraintViolationException) {
                String errorMessage = throwable.getMessage();
                response.setErrors(new ArrayList<>(Arrays.asList(errorMessage)));
            }
            throwable = throwable.getCause();
        }       
        return new ResponseEntity<Object>(response, HttpStatus.CONFLICT);
    }
    }
    

    【讨论】:

    • 你可能没有理解这个问题...我想做一些类似 if(throwable.getCause().equals("somecause")) return new ResponseEntity; else (见我的编辑)
    猜你喜欢
    • 2014-08-26
    • 2018-07-13
    • 1970-01-01
    • 2022-10-14
    • 2015-12-15
    • 2019-06-04
    • 2023-03-21
    • 2019-07-06
    相关资源
    最近更新 更多