ControllerAdvice有条件地处理异常

问题描述

我有一个控制器建议来处理我的REST控制器中的异常行为,并且遇到一种情况,当我必须有条件地处理sqlIntegrityConstraintViolationException时,该消息中有特定消息(重复密钥的消息),返回{ {1}},让其他的由认处理程序处理(返回409错误代码)。

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

  1. 根据我的条件在else分支上抛出一个新的500,所以处理由Spring完成。
  2. 显式调用常规异常处理程序(例如从我的else分支内部调用Exception)。

我有一种“适当的”方法return handleGeneralException(exception)中一种异常的一部分传递给除“原始”处理程序之外的另一个处理程序?

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

ControllerAdvice

解决方法

具有一个自定义异常类,然后在您将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);
}
,

下面的代码将捕获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);
}
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...