全局异常处理(容易忘在这里记录下)(直接抄方式二即可)
方式一
1 /** 2 * 全局异常处理类,能够处理到controller、filter、interceptro所抛出的异常 3 * 不使用HandlerExceptionResolver、结合两者使用(ControllerAdvice|ErrorController) 4 */ 5 @RestControllerAdvice 6 @Controller 7 public class GlobleAdviceAndErrorController implements ErrorController { 8 9 Logger logger = LoggerFactory.getLogger(this.getClass()); 10 11 public static final String ERROR_PATH="/error"; 12 13 @RequestMapping(ERROR_PATH) 14 @ResponseBody 15 @ResponseStatus(HttpStatus.OK) 16 public ApiResult<Object> error(HttpServletRequest request, HttpServletResponse response) { 17 18 //获取错误信息 19 Integer status = (Integer) request.getAttribute("javax.servlet.error.status_code"); 20 Throwable exception = (Throwable) request.getAttribute("javax.servlet.error.exception"); 21 // Object servlet_name = request.getAttribute("javax.servlet.error.servlet_name"); 22 // Object message = request.getAttribute("javax.servlet.error.message"); 23 // String uri = (String) request.getAttribute("javax.servlet.error.request_uri"); 24 25 26 if (status > 400 && status < 500) { 27 response.setStatus(200); 28 return ApiResult.error(status.toString(), "请求无效"); 29 } 30 if (exception==null){ 31 return ApiResult.error(status.toString(), "请求无效"); 32 } 33 if (status == 400) { 34 return ApiResult.error(status.toString(), exception.getMessage()); 35 } 36 37 return buildErrorResult(exception); 38 } 39 40 @ExceptionHandler(Exception.class) 41 @ResponseBody 42 @ResponseStatus(HttpStatus.OK) 43 public ApiResult<Object> handleExeption(Exception ex) { 44 return buildErrorResult(ex); 45 } 46 47 //处理自定义(业务逻辑错误)异常,不需要记录日志 48 @ExceptionHandler(BaseException.class) 49 @ResponseBody 50 @ResponseStatus(HttpStatus.OK) 51 public ApiResult<Object> handleBaseExeption(BaseException ex) { 52 logger.error("业务异常code:{},{}",ex.getCode(),ex.getMessage()); 53 return new ApiResult<>(ex.getCode(),ex.getMessage()); 54 } 55 56 private ApiResult<Object> buildErrorResult(Throwable exception) { 57 ApiResult result = new ApiResult(); 58 String err_code = java.util.UUID.randomUUID().toString(); 59 60 //返回值 61 if (exception != null) { 62 BaseException baseException = null; 63 if (exception instanceof BaseException) { 64 baseException = (BaseException) exception; 65 } else if (exception.getCause() instanceof BaseException) { 66 baseException = (BaseException) exception.getCause(); 67 }else if (exception instanceof MethodArgumentNotValidException){ 68 baseException= new BaseException(ExceptionCodeEnum.PARAMETER_ERROR.getCode(),exception.getMessage()); 69 } else if (exception.getCause() instanceof RuntimeException) { 70 //baseException = new BaseException(ResultCodeEnum.SERVER_INTERNAL_ERROR.getCode() + "", exception.getCause().getMessage()); 71 baseException = new BaseException(ResultCodeEnum.SERVER_INTERNAL_ERROR.getCode() + "", "编号[" + err_code + "]"); 72 } else { 73 baseException = new BaseException(ResultCodeEnum.SERVER_INTERNAL_ERROR.getCode() + "", "编号[" + err_code + "]"); 74 } 75 76 result.setCode(baseException.getCode()); 77 result.setMessage(baseException.getMessage()); 78 } else { 79 result.setCode(ResultCodeEnum.SERVER_INTERNAL_ERROR.getCode()); 80 } 81 result.setData("编号[" + err_code + "]"); 82 83 recodeExceptionLog(result, exception); 84 85 return result; 86 } 87 88 89 90 /** 91 * 记录错误日志 92 * 93 * @param result 94 * @param exception 95 */ 96 private void recodeExceptionLog(ApiResult<Object> result, Throwable exception) { 97 String errorMsg = "错误日志:"; 98 errorMsg += result.getCode() + ";" + result.getMessage() + "\r\n"; 99 errorMsg += result.getData(); 100 errorMsg += exception.getStackTrace()[0]; 101 logger.error(errorMsg,exception); 102 } 103 104 /** 105 * 校验错误拦截处理 106 * 107 * @param exception 错误信息集合 108 * @return 错误信息 109 */ 110 @ExceptionHandler(MethodArgumentNotValidException.class) 111 public ApiResult validationBodyException(MethodArgumentNotValidException exception){ 112 BindingResult result = exception.getBindingResult(); 113 if (result.hasErrors()) { 114 List<ObjectError> errors = result.getAllErrors(); 115 //取第一个 116 String message = errors.stream().map(e -> ((FieldError) e).getDefaultMessage()).filter(e->!StringUtils.isEmpty(e)).findFirst().get(); 117 if (!StringUtils.isEmpty(message)){ 118 return ApiResult.error(ExceptionCodeEnum.PARAMETER_ERROR,message); 119 } 120 } 121 return ApiResult.error(ExceptionCodeEnum.PARAMETER_ERROR,"请填写正确信息"); 122 } 123 124 /** 125 * 参数类型转换错误 126 * 127 * @param exception 错误 128 * @return 错误信息 129 */ 130 @ExceptionHandler(HttpMessageConversionException.class) 131 public ApiResult parameterTypeException(HttpMessageConversionException exception){ 132 logger.error("参数类型转换错误",exception); 133 //logger.error(exception.getCause().getLocalizedMessage()!=null?exception.getCause().getLocalizedMessage():exception.getMessage()); 134 return ApiResult.error(ExceptionCodeEnum.PARAMETER_ERROR); 135 } 136 137 138 @Override 139 public String getErrorPath() { 140 return ERROR_PATH; 141 } 142 }
方式二(可以直接抄)
@Slf4j
@RestControllerAdvice
@Controller
public class ExceptionAdvice extends AbstractErrorController {
private final ErrorAttributes errorAttributes;
@Autowired
private HttpServletRequest request;
public ExceptionAdvice(ErrorAttributes errorAttributes) {
super(errorAttributes);
this.errorAttributes = errorAttributes;
}
/**
* @param throwable
* @description: 服务器异常
* @author: shaowei
* @date: 2022-05-05 14:20:35
*/
@ExceptionHandler(Throwable.class)
public ApiResult<String> exceptionHandler(Throwable throwable) {
log.error(throwable.getMessage(), throwable);
//可以将异常发送email或者消息进行通知开发人员
return ApiResult.failed(FAILED);
}
/**
* @param e
* @description: 其它异常
* @author: shaowei
* @date: 2022-05-05 14:20:54
*/
@ExceptionHandler(value = Exception.class)
public ApiResult<String> otherExceptionHandler(Exception e) {
log.error(e.getMessage(), e);
//可以将异常发送email或者消息进行通知开发人员
return ApiResult.failed(FAILED);
}
/**
* 处理过滤器、拦截器的异常
*
* @param request
* @throws Throwable
*/
@RequestMapping("/error")
@ResponseStatus(value = HttpStatus.OK)
public ApiResult<String> handleError(HttpServletRequest request, HttpServletResponse response) throws Throwable {
ServletWebRequest webRequest = new ServletWebRequest(request);
//http响应码
HttpStatus httpStatus = getStatus(request);
int status = httpStatus.value();
//异常
Throwable throwable = errorAttributes.getError(webRequest);
if (status > HTTP_BAD_REQUEST && status < HTTP_INTERNAL_ERROR) {
return ApiResult.failed(String.valueOf(status), "请求无效");
}
if (throwable == null) {
return ApiResult.failed(String.valueOf(status), "请求无效");
}
if (status == HTTP_BAD_REQUEST) {
return ApiResult.failed(String.valueOf(status), throwable.getMessage());
}
throw throwable;
}
@Override
public String getErrorPath() {
return "/error";
}
}