diff --git a/commons/web-common/pom.xml b/commons/web-common/pom.xml
index 93f10eb14a88cee174ca0988e3b2c2dbdc728935..7118f087c8251b6a204b17f085a8b52e5ae97c7b 100644
--- a/commons/web-common/pom.xml
+++ b/commons/web-common/pom.xml
@@ -31,7 +31,7 @@
org.springframework.boot
spring-boot-configuration-processor
-
+
org.springframework
spring-tx
diff --git a/commons/web-common/src/main/java/com/schbrain/common/web/ExceptionHandingConfiguration.java b/commons/web-common/src/main/java/com/schbrain/common/web/ExceptionHandingConfiguration.java
index 6be2a5565f531669bab2e5789e619cde3cf89d93..2333b66db004bc3499b581e801092f564db2feba 100644
--- a/commons/web-common/src/main/java/com/schbrain/common/web/ExceptionHandingConfiguration.java
+++ b/commons/web-common/src/main/java/com/schbrain/common/web/ExceptionHandingConfiguration.java
@@ -18,23 +18,21 @@ import java.util.stream.Collectors;
public class ExceptionHandingConfiguration {
@Bean
- @ConditionalOnMissingBean
public GlobalExceptionHandler defaultGlobalExceptionHandler(ObjectProvider exceptionTranslators) {
- return new DefaultGlobalExceptionHandler(exceptionTranslators.orderedStream().collect(Collectors.toList()));
+ return new GlobalExceptionHandler(exceptionTranslators.orderedStream().collect(Collectors.toList()));
}
@Bean
@ConditionalOnMissingBean
- @ConditionalOnBean(GlobalExceptionHandler.class)
- public ExceptionTranslator defaultExceptionTranslator() {
- return new DefaultExceptionTranslator();
+ public ExceptionHandingWebMvcConfigurer defaultExceptionHandingWebMvcConfigurer(WebProperties webProperties, GlobalExceptionHandler exceptionHandler) {
+ return new ExceptionHandingWebMvcConfigurer(webProperties, exceptionHandler);
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnBean(GlobalExceptionHandler.class)
- public ExceptionHandlerWebMcvConfigurer defaultExceptionHandlerWebMcvConfigurer(WebProperties webProperties, GlobalExceptionHandler exceptionHandler) {
- return new ExceptionHandlerWebMcvConfigurer(webProperties, exceptionHandler);
+ public ExceptionTranslator defaultExceptionTranslator() {
+ return new DefaultExceptionTranslator();
}
}
\ No newline at end of file
diff --git a/commons/web-common/src/main/java/com/schbrain/common/web/exception/DefaultGlobalExceptionHandler.java b/commons/web-common/src/main/java/com/schbrain/common/web/exception/DefaultGlobalExceptionHandler.java
deleted file mode 100644
index dce828f792d677b8abdcde78b546c91215333051..0000000000000000000000000000000000000000
--- a/commons/web-common/src/main/java/com/schbrain/common/web/exception/DefaultGlobalExceptionHandler.java
+++ /dev/null
@@ -1,252 +0,0 @@
-package com.schbrain.common.web.exception;
-
-import cn.hutool.core.exceptions.ExceptionUtil;
-import cn.hutool.core.util.StrUtil;
-import com.schbrain.common.constants.ResponseActionConstants;
-import com.schbrain.common.exception.BaseException;
-import com.schbrain.common.web.result.ResponseDTO;
-import lombok.extern.slf4j.Slf4j;
-import org.hibernate.validator.internal.engine.path.PathImpl;
-import org.springframework.dao.DataAccessException;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.converter.HttpMessageNotReadableException;
-import org.springframework.util.ClassUtils;
-import org.springframework.validation.*;
-import org.springframework.web.*;
-import org.springframework.web.bind.*;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.web.context.request.async.AsyncRequestTimeoutException;
-import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
-import org.springframework.web.multipart.support.MissingServletRequestPartException;
-import org.springframework.web.servlet.NoHandlerFoundException;
-
-import javax.validation.ConstraintViolation;
-import javax.validation.ConstraintViolationException;
-import java.sql.SQLException;
-import java.util.*;
-
-import static com.schbrain.common.constants.ResponseCodeConstants.*;
-
-/**
- * @author liaozan
- * @since 2019/10/14
- */
-@Slf4j
-@ResponseBody
-@ResponseStatus(HttpStatus.OK)
-public class DefaultGlobalExceptionHandler implements GlobalExceptionHandler {
-
- private final List exceptionTranslators;
-
- public DefaultGlobalExceptionHandler(List exceptionTranslators) {
- this.exceptionTranslators = exceptionTranslators;
- }
-
- /************************************* Base Exception Handing *************************************/
- @ExceptionHandler(BaseException.class)
- public ResponseDTO handleBaseException(BaseException ex) {
- logError(ex);
- return buildResponse(ex, ex.getCode(), ex.getAction(), ex.getMessage());
- }
-
- /************************************* Common Exception Handing *************************************/
- @ExceptionHandler(Throwable.class)
- public ResponseDTO handleAll(Throwable ex) {
- return loggingThenBuildResponse(ex, SERVER_ERROR);
- }
-
- @ExceptionHandler(NullPointerException.class)
- public ResponseDTO handleNullPointerException(NullPointerException ex) {
- return loggingThenBuildResponse(ex, SERVER_ERROR);
- }
-
- @ExceptionHandler(IllegalArgumentException.class)
- public ResponseDTO handleIllegalArgumentException(IllegalArgumentException ex) {
- return loggingThenBuildResponse(ex, SERVER_ERROR);
- }
-
- @ExceptionHandler(IllegalStateException.class)
- public ResponseDTO handleIllegalStateException(IllegalStateException ex) {
- return loggingThenBuildResponse(ex, SERVER_ERROR);
- }
-
- @ExceptionHandler(NoHandlerFoundException.class)
- public ResponseDTO handleNoHandlerFoundException(NoHandlerFoundException ex) {
- return loggingThenBuildResponse(ex, PARAM_INVALID);
- }
-
- @ExceptionHandler(AsyncRequestTimeoutException.class)
- public ResponseDTO handleAsyncRequestTimeoutException(AsyncRequestTimeoutException ex) {
- return loggingThenBuildResponse(ex, SERVER_ERROR);
- }
-
- /************************************* SQL Exception Handing *************************************/
- @ExceptionHandler(SQLException.class)
- public ResponseDTO handleSQLException(SQLException ex) {
- return loggingThenBuildResponse(ex, SERVER_ERROR);
- }
-
- @ExceptionHandler(DataAccessException.class)
- public ResponseDTO handleDataAccessException(DataAccessException ex) {
- return loggingThenBuildResponse(ex, SERVER_ERROR);
- }
-
- /************************************* Http Request Exception Handing *************************************/
- @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
- public ResponseDTO handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException ex) {
- String errorMsg = StrUtil.format("不支持该HTTP方法: {}, 请使用 {}", ex.getMethod(), Arrays.toString(ex.getSupportedMethods()));
- log.error(errorMsg);
- return buildResponse(ex, PARAM_INVALID, errorMsg);
- }
-
- @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
- public ResponseDTO handleHttpMediaTypeNotSupportedException(HttpMediaTypeNotSupportedException ex) {
- String errorMsg = StrUtil.format("不支持该媒体类型: {}, 请使用 {}", ex.getContentType(), ex.getSupportedMediaTypes());
- log.error(errorMsg);
- return buildResponse(ex, PARAM_INVALID, errorMsg);
- }
-
- @ExceptionHandler(HttpMediaTypeNotAcceptableException.class)
- public ResponseDTO handleHttpMediaTypeNotAcceptableException(HttpMediaTypeNotAcceptableException ex) {
- String errorMsg = StrUtil.format("不支持的媒体类型, 请使用 {}", ex.getSupportedMediaTypes());
- log.error(errorMsg);
- return buildResponse(ex, PARAM_INVALID, errorMsg);
- }
-
- /************************************* Method Parameter Exception Handing *************************************/
- @ExceptionHandler(HttpMessageNotReadableException.class)
- public ResponseDTO handleHttpMessageNotReadableException(HttpMessageNotReadableException ex) {
- String errorMsg = StrUtil.format("参数解析失败, {}", ex.getMessage());
- log.error(errorMsg);
- return buildResponse(ex, PARAM_INVALID, errorMsg);
- }
-
- @ExceptionHandler(MethodArgumentTypeMismatchException.class)
- public ResponseDTO handlerMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException ex) {
- Object value = ex.getValue();
- String variableName = ex.getName();
- Class> requiredTypeClass = ex.getRequiredType();
- String requiredType = ClassUtils.getQualifiedName(requiredTypeClass == null ? Object.class : requiredTypeClass);
- String providedType = ClassUtils.getDescriptiveType(value);
- String errorMsg = StrUtil.format("参数类型不匹配, 参数名: {}, 需要: {}, 传入: {} 的 {}", variableName, requiredType, providedType, value);
- log.error(errorMsg);
- return buildResponse(ex, PARAM_INVALID, errorMsg);
- }
-
- @ExceptionHandler(MissingPathVariableException.class)
- public ResponseDTO handleMissingPathVariableException(MissingPathVariableException ex) {
- String errorMsg = StrUtil.format("丢失路径参数, 参数名: {}, 参数类型: {}", ex.getVariableName(), ex.getParameter().getParameterType());
- log.error(errorMsg);
- return buildResponse(ex, PARAM_INVALID, errorMsg);
- }
-
- @ExceptionHandler(MissingRequestCookieException.class)
- public ResponseDTO handleMissingRequestCookieException(MissingRequestCookieException ex) {
- String errorMsg = StrUtil.format("丢失Cookie参数, 参数名: {}, 参数类型: {}", ex.getCookieName(), ex.getParameter().getParameterType());
- log.error(errorMsg);
- return buildResponse(ex, PARAM_INVALID, errorMsg);
- }
-
- @ExceptionHandler(MissingRequestHeaderException.class)
- public ResponseDTO handleMissingRequestHeaderException(MissingRequestHeaderException ex) {
- String errorMsg = StrUtil.format("丢失Header参数, 参数名: {}, 参数类型: {}", ex.getHeaderName(), ex.getParameter().getParameterType());
- log.error(errorMsg);
- return buildResponse(ex, PARAM_INVALID, errorMsg);
- }
-
- @ExceptionHandler(MissingServletRequestPartException.class)
- public ResponseDTO handleMissingServletRequestPartException(MissingServletRequestPartException ex) {
- String errorMsg = StrUtil.format("丢失参数: {}", ex.getRequestPartName());
- log.error(errorMsg);
- return buildResponse(ex, PARAM_INVALID, errorMsg);
- }
-
- @ExceptionHandler(MissingServletRequestParameterException.class)
- public ResponseDTO handleServletRequestParameterException(MissingServletRequestParameterException ex) {
- String errorMsg = StrUtil.format("丢失Query参数, 参数名: {}, 参数类型: {}", ex.getParameterName(), ex.getParameterType());
- log.error(errorMsg);
- return buildResponse(ex, PARAM_INVALID, errorMsg);
- }
-
- @ExceptionHandler(ServletRequestBindingException.class)
- public ResponseDTO handleServletRequestBindingException(ServletRequestBindingException ex) {
- String errorMsg = StrUtil.format("参数绑定失败: {}", ex.getMessage());
- log.error(errorMsg);
- return buildResponse(ex, PARAM_INVALID, errorMsg);
- }
-
- /************************************* Parameter Binding Exception Handing *************************************/
- @ExceptionHandler(BindException.class)
- public ResponseDTO handleBindException(BindException ex) {
- String errorMsg = buildBindingErrorMsg(ex.getBindingResult());
- log.error(errorMsg);
- return buildResponse(ex, PARAM_INVALID, errorMsg);
- }
-
- @ExceptionHandler(ConstraintViolationException.class)
- public ResponseDTO handleConstraintViolationException(ConstraintViolationException ex) {
- String errorMsg = buildBindingErrorMsg(ex.getConstraintViolations());
- log.error(errorMsg);
- return buildResponse(ex, PARAM_INVALID, errorMsg);
- }
-
- protected ResponseDTO loggingThenBuildResponse(Throwable throwable, int code) {
- Throwable rootCause = ExceptionUtil.getRootCause(throwable);
- logError(rootCause);
- return buildResponse(rootCause, code, rootCause.getMessage());
- }
-
- protected ResponseDTO buildResponse(Throwable throwable, int code, String message) {
- return buildResponse(throwable, code, ResponseActionConstants.ALERT, message);
- }
-
- protected ResponseDTO buildResponse(Throwable throwable, int code, int action, String message) {
- ResponseDTO responseDTO = translateException(throwable, code, action, message);
- if (responseDTO != null) {
- return responseDTO;
- }
- return ResponseDTO.error(message, code, action);
- }
-
- protected ResponseDTO translateException(Throwable throwable, int code, int action, String message) {
- for (ExceptionTranslator exceptionTranslator : exceptionTranslators) {
- ResponseDTO responseDTO = exceptionTranslator.translate(throwable, code, action, message);
- if (responseDTO != null) {
- return responseDTO;
- }
- }
- return null;
- }
-
- protected String buildBindingErrorMsg(BindingResult bindingResult) {
- String prefix = "参数验证失败: ";
- StringJoiner joiner = new StringJoiner(", ");
- for (ObjectError error : bindingResult.getAllErrors()) {
- String errorMessage = Optional.ofNullable(error.getDefaultMessage()).orElse("验证失败");
- String source;
- if (error instanceof FieldError) {
- source = ((FieldError) error).getField();
- } else {
- source = error.getObjectName();
- }
- joiner.add(source + " " + errorMessage);
- }
- return prefix + joiner;
- }
-
- protected String buildBindingErrorMsg(Set> constraintViolations) {
- String prefix = "参数验证失败: ";
- StringJoiner joiner = new StringJoiner(", ");
- for (ConstraintViolation> violation : constraintViolations) {
- PathImpl propertyPath = (PathImpl) violation.getPropertyPath();
- joiner.add(propertyPath.asString() + " " + violation.getMessage());
- }
- return prefix + joiner;
- }
-
- protected void logError(Throwable throwable) {
- String exMsg = ExceptionUtil.getMessage(throwable);
- log.error(exMsg, throwable);
- }
-
-}
\ No newline at end of file
diff --git a/commons/web-common/src/main/java/com/schbrain/common/web/exception/DefaultGlobalExceptionResolver.java b/commons/web-common/src/main/java/com/schbrain/common/web/exception/DefaultGlobalExceptionResolver.java
index 4d718161542b0618fcee599b80af48f181552aeb..c7dd6e4dfe61f47217214cc566ce635f5ac5dd01 100644
--- a/commons/web-common/src/main/java/com/schbrain/common/web/exception/DefaultGlobalExceptionResolver.java
+++ b/commons/web-common/src/main/java/com/schbrain/common/web/exception/DefaultGlobalExceptionResolver.java
@@ -39,7 +39,7 @@ public class DefaultGlobalExceptionResolver extends AbstractHandlerMethodExcepti
private final HandlerMethodReturnValueHandlerComposite returnValueHandlerComposite;
- private final Map, ExceptionHandlerMethodResolver> exceptionHandlerCache = new ConcurrentHashMap<>(64);
+ private final Map, ExceptionHandlerMethodResolver> exceptionHandlerMethodResolvers = new ConcurrentHashMap<>(64);
public DefaultGlobalExceptionResolver(ExceptionHandlerExceptionResolver handlerMethodResolver, WebProperties webProperties, GlobalExceptionHandler exceptionHandler) {
this.webProperties = webProperties;
@@ -69,7 +69,7 @@ public class DefaultGlobalExceptionResolver extends AbstractHandlerMethodExcepti
}
@Override
- protected final ModelAndView doResolveHandlerMethodException(HttpServletRequest request, HttpServletResponse response, @Nullable HandlerMethod handlerMethod, Exception exception) {
+ protected ModelAndView doResolveHandlerMethodException(HttpServletRequest request, HttpServletResponse response, @Nullable HandlerMethod handlerMethod, Exception exception) {
ServletInvocableHandlerMethod exceptionHandlerMethod = createExceptionHandlerMethod(exception, handlerMethod, exceptionHandler);
if (exceptionHandlerMethod == null) {
return null;
@@ -79,7 +79,7 @@ public class DefaultGlobalExceptionResolver extends AbstractHandlerMethodExcepti
return doResolveException(webRequest, exceptionHandlerMethod, getArguments(exception, handlerMethod));
}
- protected final ModelAndView doResolveException(ServletWebRequest webRequest, ServletInvocableHandlerMethod targetMethod, Object[] arguments) {
+ protected ModelAndView doResolveException(ServletWebRequest webRequest, ServletInvocableHandlerMethod targetMethod, Object[] arguments) {
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
try {
targetMethod.invokeAndHandle(webRequest, mavContainer, arguments);
@@ -93,6 +93,7 @@ public class DefaultGlobalExceptionResolver extends AbstractHandlerMethodExcepti
return null;
}
+ @Nullable
protected ServletInvocableHandlerMethod createExceptionHandlerMethod(Exception exception, @Nullable HandlerMethod handlerMethod, Object handler) {
Method targetMethod = resolveTargetMethod(exception, handlerMethod);
if (targetMethod == null) {
@@ -104,6 +105,7 @@ public class DefaultGlobalExceptionResolver extends AbstractHandlerMethodExcepti
return exceptionHandlerMethod;
}
+ @Nullable
protected Method resolveTargetMethod(Exception exception, @Nullable HandlerMethod handlerMethod) {
Method resolvedMethod = null;
if (handlerMethod != null) {
@@ -122,7 +124,7 @@ public class DefaultGlobalExceptionResolver extends AbstractHandlerMethodExcepti
}
private ExceptionHandlerMethodResolver getHandlerMethodResolver(Class> handlerType) {
- return exceptionHandlerCache.computeIfAbsent(handlerType, key -> new ExceptionHandlerMethodResolver(handlerType));
+ return exceptionHandlerMethodResolvers.computeIfAbsent(handlerType, key -> new ExceptionHandlerMethodResolver(handlerType));
}
/**
diff --git a/commons/web-common/src/main/java/com/schbrain/common/web/exception/ExceptionHandlerWebMcvConfigurer.java b/commons/web-common/src/main/java/com/schbrain/common/web/exception/ExceptionHandingWebMvcConfigurer.java
similarity index 75%
rename from commons/web-common/src/main/java/com/schbrain/common/web/exception/ExceptionHandlerWebMcvConfigurer.java
rename to commons/web-common/src/main/java/com/schbrain/common/web/exception/ExceptionHandingWebMvcConfigurer.java
index 4c4d47078faa7da4b636c2a3d54fe9b2bb8b00de..1410be9240dd6716dcaabb3b8d1ee9300d4d2cf2 100644
--- a/commons/web-common/src/main/java/com/schbrain/common/web/exception/ExceptionHandlerWebMcvConfigurer.java
+++ b/commons/web-common/src/main/java/com/schbrain/common/web/exception/ExceptionHandingWebMvcConfigurer.java
@@ -13,13 +13,13 @@ import java.util.List;
* @since 2022/8/29
*/
@Slf4j
-public class ExceptionHandlerWebMcvConfigurer implements WebMvcConfigurer {
+public class ExceptionHandingWebMvcConfigurer implements WebMvcConfigurer {
private final WebProperties webProperties;
private final GlobalExceptionHandler globalExceptionHandler;
- public ExceptionHandlerWebMcvConfigurer(WebProperties webProperties, GlobalExceptionHandler globalExceptionHandler) {
+ public ExceptionHandingWebMvcConfigurer(WebProperties webProperties, GlobalExceptionHandler globalExceptionHandler) {
this.webProperties = webProperties;
this.globalExceptionHandler = globalExceptionHandler;
}
@@ -44,15 +44,11 @@ public class ExceptionHandlerWebMcvConfigurer implements WebMvcConfigurer {
return;
}
- addGlobalExceptionResolver(resolvers, adviceExceptionResolver);
- }
-
- protected void addGlobalExceptionResolver(List resolvers, ExceptionHandlerExceptionResolver adviceExceptionResolver) {
int index = resolvers.indexOf(adviceExceptionResolver) + 1;
- resolvers.add(index, createGlobalExceptionResolver(adviceExceptionResolver));
+ resolvers.add(index, createExceptionResolver(adviceExceptionResolver));
}
- protected HandlerExceptionResolver createGlobalExceptionResolver(ExceptionHandlerExceptionResolver adviceExceptionResolver) {
+ protected HandlerExceptionResolver createExceptionResolver(ExceptionHandlerExceptionResolver adviceExceptionResolver) {
return new DefaultGlobalExceptionResolver(adviceExceptionResolver, webProperties, globalExceptionHandler);
}
diff --git a/commons/web-common/src/main/java/com/schbrain/common/web/exception/GlobalExceptionHandler.java b/commons/web-common/src/main/java/com/schbrain/common/web/exception/GlobalExceptionHandler.java
index 4138a43df21d4d878b9397a21fd0daf971ac01ac..0b6f76696535ae4ca12a27974ec6c30bf041e5e4 100644
--- a/commons/web-common/src/main/java/com/schbrain/common/web/exception/GlobalExceptionHandler.java
+++ b/commons/web-common/src/main/java/com/schbrain/common/web/exception/GlobalExceptionHandler.java
@@ -1,11 +1,252 @@
package com.schbrain.common.web.exception;
+import cn.hutool.core.exceptions.ExceptionUtil;
+import cn.hutool.core.util.StrUtil;
+import com.schbrain.common.constants.ResponseActionConstants;
+import com.schbrain.common.exception.BaseException;
+import com.schbrain.common.web.result.ResponseDTO;
+import lombok.extern.slf4j.Slf4j;
+import org.hibernate.validator.internal.engine.path.PathImpl;
+import org.springframework.dao.DataAccessException;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.converter.HttpMessageNotReadableException;
+import org.springframework.util.ClassUtils;
+import org.springframework.validation.*;
+import org.springframework.web.*;
+import org.springframework.web.bind.*;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.context.request.async.AsyncRequestTimeoutException;
+import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
+import org.springframework.web.multipart.support.MissingServletRequestPartException;
+import org.springframework.web.servlet.NoHandlerFoundException;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.ConstraintViolationException;
+import java.sql.SQLException;
+import java.util.*;
+
+import static com.schbrain.common.constants.ResponseCodeConstants.*;
+
/**
- * 标记接口
- *
* @author liaozan
- * @since 2022/10/26
+ * @since 2019/10/14
*/
-public interface GlobalExceptionHandler {
+@Slf4j
+@ResponseBody
+@ResponseStatus(HttpStatus.OK)
+public class GlobalExceptionHandler {
+
+ private final List exceptionTranslators;
+
+ public GlobalExceptionHandler(List exceptionTranslators) {
+ this.exceptionTranslators = exceptionTranslators;
+ }
+
+ /************************************* Base Exception Handing *************************************/
+ @ExceptionHandler(BaseException.class)
+ public ResponseDTO handleBaseException(BaseException ex) {
+ logError(ex);
+ return buildResponse(ex, ex.getCode(), ex.getAction(), ex.getMessage());
+ }
+
+ /************************************* Common Exception Handing *************************************/
+ @ExceptionHandler(Throwable.class)
+ public ResponseDTO handleAll(Throwable ex) {
+ return loggingThenBuildResponse(ex, SERVER_ERROR);
+ }
+
+ @ExceptionHandler(NullPointerException.class)
+ public ResponseDTO handleNullPointerException(NullPointerException ex) {
+ return loggingThenBuildResponse(ex, SERVER_ERROR);
+ }
+
+ @ExceptionHandler(IllegalArgumentException.class)
+ public ResponseDTO handleIllegalArgumentException(IllegalArgumentException ex) {
+ return loggingThenBuildResponse(ex, SERVER_ERROR);
+ }
+
+ @ExceptionHandler(IllegalStateException.class)
+ public ResponseDTO handleIllegalStateException(IllegalStateException ex) {
+ return loggingThenBuildResponse(ex, SERVER_ERROR);
+ }
+
+ @ExceptionHandler(NoHandlerFoundException.class)
+ public ResponseDTO handleNoHandlerFoundException(NoHandlerFoundException ex) {
+ return loggingThenBuildResponse(ex, PARAM_INVALID);
+ }
+
+ @ExceptionHandler(AsyncRequestTimeoutException.class)
+ public ResponseDTO handleAsyncRequestTimeoutException(AsyncRequestTimeoutException ex) {
+ return loggingThenBuildResponse(ex, SERVER_ERROR);
+ }
+
+ /************************************* SQL Exception Handing *************************************/
+ @ExceptionHandler(SQLException.class)
+ public ResponseDTO handleSQLException(SQLException ex) {
+ return loggingThenBuildResponse(ex, SERVER_ERROR);
+ }
+
+ @ExceptionHandler(DataAccessException.class)
+ public ResponseDTO handleDataAccessException(DataAccessException ex) {
+ return loggingThenBuildResponse(ex, SERVER_ERROR);
+ }
+
+ /************************************* Http Request Exception Handing *************************************/
+ @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
+ public ResponseDTO handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException ex) {
+ String errorMsg = StrUtil.format("不支持该HTTP方法: {}, 请使用 {}", ex.getMethod(), Arrays.toString(ex.getSupportedMethods()));
+ log.error(errorMsg);
+ return buildResponse(ex, PARAM_INVALID, errorMsg);
+ }
+
+ @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
+ public ResponseDTO handleHttpMediaTypeNotSupportedException(HttpMediaTypeNotSupportedException ex) {
+ String errorMsg = StrUtil.format("不支持该媒体类型: {}, 请使用 {}", ex.getContentType(), ex.getSupportedMediaTypes());
+ log.error(errorMsg);
+ return buildResponse(ex, PARAM_INVALID, errorMsg);
+ }
+
+ @ExceptionHandler(HttpMediaTypeNotAcceptableException.class)
+ public ResponseDTO handleHttpMediaTypeNotAcceptableException(HttpMediaTypeNotAcceptableException ex) {
+ String errorMsg = StrUtil.format("不支持的媒体类型, 请使用 {}", ex.getSupportedMediaTypes());
+ log.error(errorMsg);
+ return buildResponse(ex, PARAM_INVALID, errorMsg);
+ }
+
+ /************************************* Method Parameter Exception Handing *************************************/
+ @ExceptionHandler(HttpMessageNotReadableException.class)
+ public ResponseDTO handleHttpMessageNotReadableException(HttpMessageNotReadableException ex) {
+ String errorMsg = StrUtil.format("参数解析失败, {}", ex.getMessage());
+ log.error(errorMsg);
+ return buildResponse(ex, PARAM_INVALID, errorMsg);
+ }
+
+ @ExceptionHandler(MethodArgumentTypeMismatchException.class)
+ public ResponseDTO handlerMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException ex) {
+ Object value = ex.getValue();
+ String variableName = ex.getName();
+ Class> requiredTypeClass = ex.getRequiredType();
+ String requiredType = ClassUtils.getQualifiedName(requiredTypeClass == null ? Object.class : requiredTypeClass);
+ String providedType = ClassUtils.getDescriptiveType(value);
+ String errorMsg = StrUtil.format("参数类型不匹配, 参数名: {}, 需要: {}, 传入: {} 的 {}", variableName, requiredType, providedType, value);
+ log.error(errorMsg);
+ return buildResponse(ex, PARAM_INVALID, errorMsg);
+ }
+
+ @ExceptionHandler(MissingPathVariableException.class)
+ public ResponseDTO handleMissingPathVariableException(MissingPathVariableException ex) {
+ String errorMsg = StrUtil.format("丢失路径参数, 参数名: {}, 参数类型: {}", ex.getVariableName(), ex.getParameter().getParameterType());
+ log.error(errorMsg);
+ return buildResponse(ex, PARAM_INVALID, errorMsg);
+ }
+
+ @ExceptionHandler(MissingRequestCookieException.class)
+ public ResponseDTO handleMissingRequestCookieException(MissingRequestCookieException ex) {
+ String errorMsg = StrUtil.format("丢失Cookie参数, 参数名: {}, 参数类型: {}", ex.getCookieName(), ex.getParameter().getParameterType());
+ log.error(errorMsg);
+ return buildResponse(ex, PARAM_INVALID, errorMsg);
+ }
+
+ @ExceptionHandler(MissingRequestHeaderException.class)
+ public ResponseDTO handleMissingRequestHeaderException(MissingRequestHeaderException ex) {
+ String errorMsg = StrUtil.format("丢失Header参数, 参数名: {}, 参数类型: {}", ex.getHeaderName(), ex.getParameter().getParameterType());
+ log.error(errorMsg);
+ return buildResponse(ex, PARAM_INVALID, errorMsg);
+ }
+
+ @ExceptionHandler(MissingServletRequestPartException.class)
+ public ResponseDTO handleMissingServletRequestPartException(MissingServletRequestPartException ex) {
+ String errorMsg = StrUtil.format("丢失参数: {}", ex.getRequestPartName());
+ log.error(errorMsg);
+ return buildResponse(ex, PARAM_INVALID, errorMsg);
+ }
+
+ @ExceptionHandler(MissingServletRequestParameterException.class)
+ public ResponseDTO handleServletRequestParameterException(MissingServletRequestParameterException ex) {
+ String errorMsg = StrUtil.format("丢失Query参数, 参数名: {}, 参数类型: {}", ex.getParameterName(), ex.getParameterType());
+ log.error(errorMsg);
+ return buildResponse(ex, PARAM_INVALID, errorMsg);
+ }
+
+ @ExceptionHandler(ServletRequestBindingException.class)
+ public ResponseDTO handleServletRequestBindingException(ServletRequestBindingException ex) {
+ String errorMsg = StrUtil.format("参数绑定失败: {}", ex.getMessage());
+ log.error(errorMsg);
+ return buildResponse(ex, PARAM_INVALID, errorMsg);
+ }
+
+ /************************************* Parameter Binding Exception Handing *************************************/
+ @ExceptionHandler(BindException.class)
+ public ResponseDTO handleBindException(BindException ex) {
+ String errorMsg = buildBindingErrorMsg(ex.getBindingResult());
+ log.error(errorMsg);
+ return buildResponse(ex, PARAM_INVALID, errorMsg);
+ }
+
+ @ExceptionHandler(ConstraintViolationException.class)
+ public ResponseDTO handleConstraintViolationException(ConstraintViolationException ex) {
+ String errorMsg = buildBindingErrorMsg(ex.getConstraintViolations());
+ log.error(errorMsg);
+ return buildResponse(ex, PARAM_INVALID, errorMsg);
+ }
+
+ private ResponseDTO loggingThenBuildResponse(Throwable throwable, int code) {
+ Throwable rootCause = ExceptionUtil.getRootCause(throwable);
+ logError(rootCause);
+ return buildResponse(rootCause, code, rootCause.getMessage());
+ }
+
+ private ResponseDTO buildResponse(Throwable throwable, int code, String message) {
+ return buildResponse(throwable, code, ResponseActionConstants.ALERT, message);
+ }
+
+ private ResponseDTO buildResponse(Throwable throwable, int code, int action, String message) {
+ ResponseDTO responseDTO = translateException(throwable, code, action, message);
+ if (responseDTO != null) {
+ return responseDTO;
+ }
+ return ResponseDTO.error(message, code, action);
+ }
+
+ private ResponseDTO translateException(Throwable throwable, int code, int action, String message) {
+ for (ExceptionTranslator exceptionTranslator : exceptionTranslators) {
+ ResponseDTO responseDTO = exceptionTranslator.translate(throwable, code, action, message);
+ if (responseDTO != null) {
+ return responseDTO;
+ }
+ }
+ return null;
+ }
+
+ private String buildBindingErrorMsg(BindingResult bindingResult) {
+ String prefix = "参数验证失败: ";
+ StringJoiner joiner = new StringJoiner(", ");
+ for (ObjectError error : bindingResult.getAllErrors()) {
+ String errorMessage = Optional.ofNullable(error.getDefaultMessage()).orElse("验证失败");
+ String source;
+ if (error instanceof FieldError) {
+ source = ((FieldError) error).getField();
+ } else {
+ source = error.getObjectName();
+ }
+ joiner.add(source + " " + errorMessage);
+ }
+ return prefix + joiner;
+ }
+
+ private String buildBindingErrorMsg(Set> constraintViolations) {
+ String prefix = "参数验证失败: ";
+ StringJoiner joiner = new StringJoiner(", ");
+ for (ConstraintViolation> violation : constraintViolations) {
+ PathImpl propertyPath = (PathImpl) violation.getPropertyPath();
+ joiner.add(propertyPath.asString() + " " + violation.getMessage());
+ }
+ return prefix + joiner;
+ }
+
+ private void logError(Throwable throwable) {
+ String exMsg = ExceptionUtil.getMessage(throwable);
+ log.error(exMsg, throwable);
+ }
}
\ No newline at end of file