From b8b8f70e3593bf8c09533ac3c11fe38518fab340 Mon Sep 17 00:00:00 2001 From: hongawen <83944980@qq.com> Date: Fri, 1 Nov 2024 13:38:32 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BE=AE=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../njcn/gather/handler/ControllerUtil.java | 37 +++ .../GlobalBusinessExceptionHandler.java | 253 ++++++++++++++++++ 2 files changed, 290 insertions(+) create mode 100644 entrance/src/main/java/com/njcn/gather/handler/ControllerUtil.java create mode 100644 entrance/src/main/java/com/njcn/gather/handler/GlobalBusinessExceptionHandler.java diff --git a/entrance/src/main/java/com/njcn/gather/handler/ControllerUtil.java b/entrance/src/main/java/com/njcn/gather/handler/ControllerUtil.java new file mode 100644 index 00000000..e988c270 --- /dev/null +++ b/entrance/src/main/java/com/njcn/gather/handler/ControllerUtil.java @@ -0,0 +1,37 @@ +package com.njcn.gather.handler; + +import com.njcn.common.pojo.constant.LogInfo; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.MethodArgumentNotValidException; + +import java.lang.reflect.Method; +import java.util.Objects; + +/** + * @author hongawen + * @version 1.0.0 + * @date 2021年06月22日 10:25 + */ +@Slf4j +public class ControllerUtil { + + /** + * 针对methodArgumentNotValidException 异常的处理 + * @author cdf + */ + public static String getMethodArgumentNotValidException(MethodArgumentNotValidException methodArgumentNotValidException) { + String operate = LogInfo.UNKNOWN_OPERATE; + Method method = null; + try { + method = methodArgumentNotValidException.getParameter().getMethod(); + if (!Objects.isNull(method) && method.isAnnotationPresent(ApiOperation.class)) { + ApiOperation apiOperation = method.getAnnotation(ApiOperation.class); + operate = apiOperation.value(); + } + }catch (Exception e){ + log.error("根据方法参数非法异常获取@ApiOperation注解值失败,参数非法异常信息:{},方法名:{},异常信息:{}",methodArgumentNotValidException.getMessage(),method,e.getMessage()); + } + return operate; + } +} diff --git a/entrance/src/main/java/com/njcn/gather/handler/GlobalBusinessExceptionHandler.java b/entrance/src/main/java/com/njcn/gather/handler/GlobalBusinessExceptionHandler.java new file mode 100644 index 00000000..9e7e6d8f --- /dev/null +++ b/entrance/src/main/java/com/njcn/gather/handler/GlobalBusinessExceptionHandler.java @@ -0,0 +1,253 @@ +package com.njcn.gather.handler; + +import cn.hutool.core.text.StrFormatter; +import cn.hutool.core.util.StrUtil; +import com.njcn.common.pojo.enums.response.CommonResponseEnum; +import com.njcn.common.pojo.exception.BusinessException; +import com.njcn.common.pojo.response.HttpResult; +import com.njcn.common.utils.LogUtil; +import com.njcn.web.utils.HttpResultUtil; +import com.njcn.web.utils.ReflectCommonUtil; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.json.JSONException; +import org.springframework.validation.ObjectError; +import org.springframework.web.HttpMediaTypeNotSupportedException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.util.NestedServletException; + +import javax.servlet.http.HttpServletRequest; +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * 全局通用业务异常处理器 + * + * @author hongawen + * @version 1.0.0 + * @date 2021年04月20日 18:04 + */ +@Slf4j +@AllArgsConstructor +@RestControllerAdvice +public class GlobalBusinessExceptionHandler { + +// private final ILogService logService; + + /** + * 捕获业务功能异常,通常为业务数据抛出的异常 + * + * @param businessException 业务异常 + */ + @ExceptionHandler(BusinessException.class) + public HttpResult handleBusinessException(HttpServletRequest httpServletRequest, BusinessException businessException) { + String operate = ReflectCommonUtil.getMethodDescribeByException(businessException); +// logService.recodeBusinessExceptionLog(businessException, httpServletRequest, businessException.getMessage()); + //判断方法上是否有自定义注解,做特殊处理 + Method method = ReflectCommonUtil.getMethod(businessException); +// if (!Objects.isNull(method)){ +// if(method.isAnnotationPresent(ReturnMsg.class)){ +// return HttpResultUtil.assembleResult(businessException.getCode(), null, StrFormatter.format("{}",businessException.getMessage())); +// } +// } + return HttpResultUtil.assembleBusinessExceptionResult(businessException, null, operate); + } + + + /** + * 空指针异常捕捉 + * + * @param nullPointerException 空指针异常 + */ + @ExceptionHandler(NullPointerException.class) + public HttpResult handleNullPointerException(HttpServletRequest httpServletRequest, NullPointerException nullPointerException) { + LogUtil.logExceptionStackInfo(CommonResponseEnum.NULL_POINTER_EXCEPTION.getMessage(), nullPointerException); +// logService.recodeBusinessExceptionLog(nullPointerException, httpServletRequest, CommonResponseEnum.NULL_POINTER_EXCEPTION.getMessage()); + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.NULL_POINTER_EXCEPTION, null, ReflectCommonUtil.getMethodDescribeByException(nullPointerException)); + } + + /** + * 算数运算异常 + * + * @param arithmeticException 算数运算异常,由于除数为0引起的异常 + */ + @ExceptionHandler(ArithmeticException.class) + public HttpResult handleArithmeticException(HttpServletRequest httpServletRequest, ArithmeticException arithmeticException) { + LogUtil.logExceptionStackInfo(CommonResponseEnum.ARITHMETIC_EXCEPTION.getMessage(), arithmeticException); +// logService.recodeBusinessExceptionLog(arithmeticException, httpServletRequest, CommonResponseEnum.ARITHMETIC_EXCEPTION.getMessage()); + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.ARITHMETIC_EXCEPTION, null, ReflectCommonUtil.getMethodDescribeByException(arithmeticException)); + } + + /** + * 类型转换异常捕捉 + * + * @param classCastException 类型转换异常 + */ + @ExceptionHandler(ClassCastException.class) + public HttpResult handleClassCastException(HttpServletRequest httpServletRequest, ClassCastException classCastException) { + LogUtil.logExceptionStackInfo(CommonResponseEnum.CLASS_CAST_EXCEPTION.getMessage(), classCastException); +// logService.recodeBusinessExceptionLog(classCastException, httpServletRequest, CommonResponseEnum.CLASS_CAST_EXCEPTION.getMessage()); + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.CLASS_CAST_EXCEPTION, null, ReflectCommonUtil.getMethodDescribeByException(classCastException)); + } + + + /** + * 索引下标越界异常捕捉 + * + * @param indexOutOfBoundsException 索引下标越界异常 + */ + @ExceptionHandler(IndexOutOfBoundsException.class) + public HttpResult handleIndexOutOfBoundsException(HttpServletRequest httpServletRequest, IndexOutOfBoundsException indexOutOfBoundsException) { + LogUtil.logExceptionStackInfo(CommonResponseEnum.INDEX_OUT_OF_BOUNDS_EXCEPTION.getMessage(), indexOutOfBoundsException); +// logService.recodeBusinessExceptionLog(indexOutOfBoundsException, httpServletRequest, CommonResponseEnum.INDEX_OUT_OF_BOUNDS_EXCEPTION.getMessage()); + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.INDEX_OUT_OF_BOUNDS_EXCEPTION, null, ReflectCommonUtil.getMethodDescribeByException(indexOutOfBoundsException)); + } + + /** + * 前端请求后端,请求中参数的媒体方式不支持异常 + * + * @param httpMediaTypeNotSupportedException 请求中参数的媒体方式不支持异常 + */ + @ExceptionHandler(HttpMediaTypeNotSupportedException.class) + public HttpResult httpMediaTypeNotSupportedExceptionHandler(HttpServletRequest httpServletRequest, HttpMediaTypeNotSupportedException httpMediaTypeNotSupportedException) { + LogUtil.logExceptionStackInfo(CommonResponseEnum.HTTP_MEDIA_TYPE_NOT_SUPPORTED_EXCEPTION.getMessage(), httpMediaTypeNotSupportedException); + // 然后提取错误提示信息进行返回 +// logService.recodeBusinessExceptionLog(httpMediaTypeNotSupportedException, httpServletRequest, CommonResponseEnum.HTTP_MEDIA_TYPE_NOT_SUPPORTED_EXCEPTION.getMessage()); + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.HTTP_MEDIA_TYPE_NOT_SUPPORTED_EXCEPTION, null, ReflectCommonUtil.getMethodDescribeByException(httpMediaTypeNotSupportedException)); + } + + /** + * 前端请求后端,参数校验异常捕捉 + * RequestBody注解参数异常 + * + * @param methodArgumentNotValidException 参数校验异常 + */ + @ExceptionHandler(MethodArgumentNotValidException.class) + public HttpResult methodArgumentNotValidExceptionHandler(HttpServletRequest httpServletRequest, MethodArgumentNotValidException methodArgumentNotValidException) { + // 从异常对象中拿到allErrors数据 + String messages = methodArgumentNotValidException.getBindingResult().getAllErrors() + .stream().map(ObjectError::getDefaultMessage).collect(Collectors.joining(";")); + // 然后提取错误提示信息进行返回 + LogUtil.njcnDebug(log, "参数校验异常,异常为:{}", messages); +// logService.recodeBusinessExceptionLog(methodArgumentNotValidException, httpServletRequest, CommonResponseEnum.METHOD_ARGUMENT_NOT_VALID_EXCEPTION.getMessage()); + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.METHOD_ARGUMENT_NOT_VALID_EXCEPTION, messages, ControllerUtil.getMethodArgumentNotValidException(methodArgumentNotValidException)); + } + + /** + * 前端请求后端,参数校验异常捕捉 + * PathVariable注解、RequestParam注解参数异常 + * + * @param constraintViolationException 参数校验异常 + */ + @ExceptionHandler(ConstraintViolationException.class) + public HttpResult constraintViolationExceptionExceptionHandler(HttpServletRequest httpServletRequest, ConstraintViolationException constraintViolationException) { + String exceptionMessage = constraintViolationException.getMessage(); + StringBuilder messages = new StringBuilder(); + if (exceptionMessage.indexOf(StrUtil.COMMA) > 0) { + String[] tempMessage = exceptionMessage.split(StrUtil.COMMA); + Stream.of(tempMessage).forEach(message -> { + messages.append(message.substring(message.indexOf(StrUtil.COLON) + 2)).append(';'); + }); + } else { + messages.append(exceptionMessage.substring(exceptionMessage.indexOf(StrUtil.COLON) + 2)); + } + // 然后提取错误提示信息进行返回 + LogUtil.njcnDebug(log, "参数校验异常,异常为:{}", messages); +// logService.recodeBusinessExceptionLog(constraintViolationException, httpServletRequest, CommonResponseEnum.METHOD_ARGUMENT_NOT_VALID_EXCEPTION.getMessage()); + List> constraintViolationList = new ArrayList<>(constraintViolationException.getConstraintViolations()); + ConstraintViolation constraintViolation = constraintViolationList.get(0); + Class rootBeanClass = constraintViolation.getRootBeanClass(); + //判断校验参数异常捕获的根源是controller还是service处 + if (rootBeanClass.getName().endsWith("Controller")) { + String methodName = constraintViolation.getPropertyPath().toString().substring(0, constraintViolation.getPropertyPath().toString().indexOf(StrUtil.DOT)); + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.METHOD_ARGUMENT_NOT_VALID_EXCEPTION, messages.toString(), ReflectCommonUtil.getMethodDescribeByClassAndMethodName(rootBeanClass, methodName)); + } else { + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.METHOD_ARGUMENT_NOT_VALID_EXCEPTION, messages.toString(), ReflectCommonUtil.getMethodDescribeByException(constraintViolationException)); + } + + } + + + /** + * 索引下标越界异常捕捉 + * + * @param illegalArgumentException 参数校验异常 + */ + @ExceptionHandler(IllegalArgumentException.class) + public HttpResult handleIndexOutOfBoundsException(HttpServletRequest httpServletRequest, IllegalArgumentException illegalArgumentException) { + LogUtil.logExceptionStackInfo(CommonResponseEnum.ILLEGAL_ARGUMENT_EXCEPTION.getMessage(), illegalArgumentException); +// logService.recodeBusinessExceptionLog(illegalArgumentException, httpServletRequest, CommonResponseEnum.ILLEGAL_ARGUMENT_EXCEPTION.getMessage()); + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.ILLEGAL_ARGUMENT_EXCEPTION, illegalArgumentException.getMessage(), ReflectCommonUtil.getMethodDescribeByException(illegalArgumentException)); + } + +// /** +// * 表格校验异常 +// * +// * @param excelAnalysisException 表格校验异常 +// */ +// @ExceptionHandler(ExcelAnalysisException.class) +// public HttpResult handleExcelAnalysisException(HttpServletRequest httpServletRequest, ExcelAnalysisException excelAnalysisException) { +// LogUtil.logExceptionStackInfo(CommonResponseEnum.ILLEGAL_ARGUMENT_EXCEPTION.getMessage(), excelAnalysisException); +// // logService.recodeBusinessExceptionLog(excelAnalysisException, httpServletRequest,CommonResponseEnum.ILLEGAL_ARGUMENT_EXCEPTION.getMessage()); +// return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.ILLEGAL_ARGUMENT_EXCEPTION, excelAnalysisException.getCause().getMessage(), ReflectCommonUtil.getMethodDescribeByException(excelAnalysisException)); +// } + + + /** + * 未声明异常捕捉 + * + * @param exception 未声明异常 + */ + @ExceptionHandler(Exception.class) + public HttpResult handleException(HttpServletRequest httpServletRequest, Exception exception) { + //针对fallbackFactory降级异常特殊处理 + Exception tempException = exception; + String exceptionCause = CommonResponseEnum.UN_DECLARE.getMessage(); + String code = CommonResponseEnum.UN_DECLARE.getCode(); + if (exception instanceof NestedServletException) { + Throwable cause = exception.getCause(); + if (cause instanceof AssertionError) { + if (cause.getCause() instanceof BusinessException) { + tempException = (BusinessException) cause.getCause(); + BusinessException tempBusinessException = (BusinessException) cause.getCause(); + exceptionCause = tempBusinessException.getMessage(); + code = tempBusinessException.getCode(); + } + } + } + LogUtil.logExceptionStackInfo(exceptionCause, tempException); +// logService.recodeBusinessExceptionLog(tempException, httpServletRequest, exceptionCause); + //判断方法上是否有自定义注解,做特殊处理 +// Method method = ReflectCommonUtil.getMethod(exception); +// if (!Objects.isNull(method)){ +// if(method.isAnnotationPresent(ReturnMsg.class)){ +// return HttpResultUtil.assembleResult(code, null, StrFormatter.format("{}",exceptionCause)); +// } +// } + return HttpResultUtil.assembleResult(code, null, StrFormatter.format("{}{}{}", ReflectCommonUtil.getMethodDescribeByException(tempException), StrUtil.C_COMMA, exceptionCause)); + } + + + + + /** + * json解析异常 + * + * @param jsonException json参数 + */ + @ExceptionHandler(JSONException.class) + public HttpResult handleIndexOutOfBoundsException(HttpServletRequest httpServletRequest, JSONException jsonException) { + LogUtil.logExceptionStackInfo(CommonResponseEnum.JSON_CONVERT_EXCEPTION.getMessage(), jsonException); +// logService.recodeBusinessExceptionLog(jsonException, httpServletRequest, CommonResponseEnum.JSON_CONVERT_EXCEPTION.getMessage()); + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.JSON_CONVERT_EXCEPTION, jsonException.getMessage(), ReflectCommonUtil.getMethodDescribeByException(jsonException)); + } + +}