问题描述
我有一个控制器建议来处理我的REST控制器中的异常行为,并且遇到一种情况,当我必须有条件地处理sqlIntegrityConstraintViolationException
时,该消息中有特定消息(重复密钥的消息),返回{ {1}},让其他的由默认处理程序处理(返回409
错误代码)。
我正在考虑两种可能的方法来实现这一目标:
我有一种“适当的”方法将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);
}
}