我正在尝试使用@ControllerAdvice
处理Spring启动应用程序中的异常。我不希望每种类型的异常都有单独的方法。我想只使用一个主类为@ExceptionHandler(Exception.class)
我试着在下面正确处理异常,但问题是我还想为不同类型的异常设置不同类型的状态代码。
这里我得到500
的每种类型的异常。
任何人都可以告诉我如何为不同类型的异常设置不同的状态代码吗?
@ControllerAdvice
public class RestExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<Object> handleAllExceptionMethod(Exception ex,WebRequest requset) {
ExceptionMessage exceptionMessageObj = new ExceptionMessage();
exceptionMessageObj.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
exceptionMessageObj.setMessage(ex.getLocalizedMessage());
exceptionMessageObj.setError(ex.getClass().getCanonicalName());
exceptionMessageObj.setPath(((ServletWebRequest) requset).getRequest().getServletPath());
return new ResponseEntity<>(exceptionMessageObj, new HttpHeaders(),HttpStatus.INTERNAL_SERVER_ERROR);
}
}
答案 0 :(得分:3)
您还可以采用不同的Spring方法。请注意,它不适用于本机Java异常(因为您需要向Exception类定义添加注释),这可能是您可能接受的,也可能是不可接受的。
@ResponseStatus
添加到每个例外的顶部。这样,您就不需要对异常进行任何类型检查。您甚至不需要定义自己的save()
。 Spring将处理正确的HTTP状态代码。如果您确实选择使用此方法实现@ControllerAdvice
,则可以使用注释来获取正确的状态代码:
@ControllerAdvice
(最初发布的注释解析方法here)
答案 1 :(得分:1)
您可以检查您的例外情况,并相应地返回:
@ControllerAdvice
public class RestExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity < Object > handleAllExceptionMethod(Exception ex, WebRequest requset) {
if (ex instanceof MyCustomException1) {
// Return error code 500
} else {
// return error code 404
}
}
答案 2 :(得分:1)
您可以根据Exception的类型设置不同的状态代码。
HttpStatus statuscode = HttpStatus.INTERNAL_SERVER_ERROR;
if(ex instanceof ExceptionClass1){
statuscode = HttpStatus.BAD_REQUEST;
}else if(ex instanceof ExceptionClass2){
statuscode = HttpStatus.FORBIDDEN;
}
答案 3 :(得分:1)
我首先质疑你的需求。为什么要在一个地方进行所有异常处理?
与其他需求相反 - 让响应代码可配置。
您有两种选择:
我更喜欢后者,如果你害怕你的代码会被复制 - 请看下面的内容:
@RestControllerAdvice
public class ExceptionHandler {
@ExceptionHandler(YourException1.class)
public ResponseEntity<ExceptionMessage> handleYourException1(YourException1 ex, WebRequest requset) {
return commonHandler(HttpStatus.INTERNAL_SERVER_ERROR, ex, requset);
}
public ResponseEntity<ExceptionMessage> commonHandler(HttpStatus status, Exception ex, WebRequest requset) {
ExceptionMessage exceptionMessageObj = new ExceptionMessage();
exceptionMessageObj.setStatus(status.value());
exceptionMessageObj.setMessage(ex.getLocalizedMessage());
exceptionMessageObj.setError(ex.getClass().getCanonicalName());
exceptionMessageObj.setPath(((ServletWebRequest) requset).getRequest().getServletPath());
return new ResponseEntity<>(exceptionMessageObj, status);
}
}
答案 4 :(得分:0)
@ControllerAdvice
public class RestExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<?> handleAllExceptions(Exception e) {
log.error("IOException: " + e.getMessage());
final Map<String, String> message = new HashMap<>();
message.put("message", "Something went wrong...");
// My custom IOException handler :)
if (e instanceof IOException) {
return ResponseEntity.unprocessableEntity().body(message);
}
return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
}
}
答案 5 :(得分:0)
您可以使用switch语句并创建多个案例:
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> exceptionHandler(Exception ex) {
ErrorResponse errorResponse = new ErrorResponse(new DescriptionInErrorResponse());
errorResponse.getError().setText(ex.getMessage());
HttpStatus httpStatus = HttpStatus.UNPROCESSABLE_ENTITY;
if (ex instanceof CustomException) {
switch (((CustomException) ex).getCode()) {
case BAD_REQUEST:
errorResponse.getError().setCode(ErrorCode.BAD_REQUEST.getName());
httpStatus = HttpStatus.BAD_REQUEST;
break;
case NOT_FOUND:
errorResponse.getError().setCode(ErrorCode.NOT_FOUND.getName());
httpStatus = HttpStatus.NOT_FOUND;
break;
case METHOD_ARGUMENT_NOT_VALID:
errorResponse.getError().setCode(ErrorCode.METHOD_ARGUMENT_NOT_VALID.getName());
httpStatus = HttpStatus.BAD_REQUEST;
break;
default:
errorResponse.getError().setCode(ErrorCode.UNKNOWN.getName());
httpStatus = HttpStatus.UNPROCESSABLE_ENTITY;
break;
}
} else if (ex instanceof ConstraintViolationException
|| ex instanceof javax.validation.ConstraintViolationException) {
errorResponse.getError().setCode(ErrorCode.BAD_REQUEST.getName());
httpStatus = HttpStatus.BAD_REQUEST;
} else if (ex instanceof MethodArgumentNotValidException) {
errorResponse.getError().setCode(ErrorCode.METHOD_ARGUMENT_NOT_VALID.getName());
httpStatus = HttpStatus.BAD_REQUEST;
} else if (ex instanceof DataIntegrityViolationException) {
errorResponse.getError().setCode(ErrorCode.INTERNAL_SERVER_ERROR.getName());
httpStatus = HttpStatus.INTERNAL_SERVER_ERROR;
} else if (ex instanceof HttpMessageNotReadableException) {
errorResponse.getError().setCode(ErrorCode.BAD_REQUEST.getName());
httpStatus = HttpStatus.BAD_REQUEST;
} else if (ex instanceof ServletRequestBindingException){
errorResponse.getError().setCode(ErrorCode.BAD_REQUEST.getName());
httpStatus = HttpStatus.BAD_REQUEST;
}
else {
log.error(ex.getMessage(), ex);
errorResponse.getError().setCode(ErrorCode.INTERNAL_SERVER_ERROR.getName());
httpStatus = HttpStatus.INTERNAL_SERVER_ERROR;
}
return ResponseEntity.status(httpStatus).body(errorResponse);
}