@ControllerAdvice可以捕获spring应用下面未被捕获异常,下面是常见代码:
代码语言:javascript复制 @ExceptionHandler(value = Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public String errorHandler(Exception ex) {
ApiResultVo<String> resultVo = new ApiResultVo<>();
resultVo.setErrorCode(500);
resultVo.setErrorMsg(ex.getMessage());
return JSON.toJSONString(resultVo);
}
@ExceptionHandler(value = MyException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public String myExceptionHandler(MyException ex) {
ApiResultVo<String> resultVo = new ApiResultVo<>();
resultVo.setErrorCode(401);
resultVo.setErrorMsg(ex.getMessage());
return JSON.toJSONString(resultVo);
}
我们在对应异常处理的上面加上ResponseStatus注解就能将系统异常转换为对应的Http状态码,这部分工作由ResponseStatusExceptionResolver这个类完成,下面是关键代码:
代码语言:javascript复制 protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) {
ResponseStatus responseStatus = AnnotatedElementUtils.findMergedAnnotation(ex.getClass(), ResponseStatus.class);
if (responseStatus != null) {
try {
return resolveResponseStatus(responseStatus, request, response, handler, ex);
}
catch (Exception resolveEx) {
logger.warn("Handling of @ResponseStatus resulted in Exception", resolveEx);
}
}
else if (ex.getCause() instanceof Exception) {
ex = (Exception) ex.getCause();
return doResolveException(request, response, handler, ex);
}
return null;
}
protected ModelAndView resolveResponseStatus(ResponseStatus responseStatus, HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) throws Exception {
int statusCode = responseStatus.code().value();
String reason = responseStatus.reason();
if (!StringUtils.hasLength(reason)) {
response.sendError(statusCode);
}
else {
String resolvedReason = (this.messageSource != null ?
this.messageSource.getMessage(reason, null, reason, LocaleContextHolder.getLocale()) :
reason);
response.sendError(statusCode, resolvedReason);
}
return new ModelAndView();
}