|
@@ -0,0 +1,141 @@
|
|
|
+package com.sxtvs.core.sls.advice;
|
|
|
+
|
|
|
+import com.sxtvs.core.sls.AliyunLogger;
|
|
|
+import jakarta.servlet.http.HttpServletRequest;
|
|
|
+import jakarta.servlet.http.HttpServletResponse;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.core.MethodParameter;
|
|
|
+import org.springframework.core.annotation.AnnotationUtils;
|
|
|
+import org.springframework.http.HttpStatus;
|
|
|
+import org.springframework.http.MediaType;
|
|
|
+import org.springframework.http.converter.HttpMessageConverter;
|
|
|
+import org.springframework.http.server.ServerHttpRequest;
|
|
|
+import org.springframework.http.server.ServerHttpResponse;
|
|
|
+import org.springframework.validation.BindingResult;
|
|
|
+import org.springframework.validation.FieldError;
|
|
|
+import org.springframework.validation.ObjectError;
|
|
|
+import org.springframework.web.bind.MethodArgumentNotValidException;
|
|
|
+import org.springframework.web.bind.annotation.ExceptionHandler;
|
|
|
+import org.springframework.web.bind.annotation.ResponseStatus;
|
|
|
+import org.springframework.web.bind.annotation.RestControllerAdvice;
|
|
|
+import org.springframework.web.multipart.MaxUploadSizeExceededException;
|
|
|
+import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
|
|
|
+
|
|
|
+import java.lang.annotation.Annotation;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+@RestControllerAdvice
|
|
|
+@Slf4j
|
|
|
+public class APIResponseAdvice implements ResponseBodyAdvice<Object> {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private AliyunLogger logger;
|
|
|
+
|
|
|
+ //自动处理APINoDataResponse,包装为APINoDataResponse
|
|
|
+
|
|
|
+
|
|
|
+ @ExceptionHandler(BizException.class)
|
|
|
+ public APINoDataResponse handleBizException(HttpServletRequest request, BizException ex, HttpServletResponse response) {
|
|
|
+ APINoDataResponse apiNoDataResponse = new APINoDataResponse();
|
|
|
+ apiNoDataResponse.setCode(ex.getErrorCode());
|
|
|
+ apiNoDataResponse.setMessage(ex.getErrorMessage());
|
|
|
+ return apiNoDataResponse;
|
|
|
+ }
|
|
|
+
|
|
|
+ @ExceptionHandler(MaxUploadSizeExceededException.class)
|
|
|
+ public APINoDataResponse handleException(HttpServletRequest request, MaxUploadSizeExceededException ex, HttpServletResponse response) {
|
|
|
+ logger.error("error", ex);
|
|
|
+ APINoDataResponse apiResponse = new APINoDataResponse();
|
|
|
+ apiResponse.setCode(-1);
|
|
|
+ apiResponse.setMessage("文件长度过长");
|
|
|
+ return apiResponse;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 拦截未知的运行时异常
|
|
|
+ *
|
|
|
+ * @author fengshuonan
|
|
|
+ * @date 2020/12/16 15:12
|
|
|
+ */
|
|
|
+ @ExceptionHandler(Throwable.class)
|
|
|
+ @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
|
|
+ public APINoDataResponse serverError(Throwable ex) {
|
|
|
+ logger.error("error", ex);
|
|
|
+ APINoDataResponse apiResponse = new APINoDataResponse();
|
|
|
+ apiResponse.setCode(-1);
|
|
|
+ apiResponse.setMessage("服务器运行异常");
|
|
|
+ return apiResponse;
|
|
|
+ }
|
|
|
+
|
|
|
+ @ExceptionHandler(MethodArgumentNotValidException.class)
|
|
|
+ @ResponseStatus(HttpStatus.BAD_REQUEST)
|
|
|
+ public APINoDataResponse validationBodyException(MethodArgumentNotValidException exception) {
|
|
|
+
|
|
|
+ BindingResult result = exception.getBindingResult();
|
|
|
+ if (result.hasErrors()) {
|
|
|
+
|
|
|
+ List<ObjectError> errors = result.getAllErrors();
|
|
|
+
|
|
|
+ errors.forEach(p -> {
|
|
|
+
|
|
|
+ FieldError fieldError = (FieldError) p;
|
|
|
+ log.error("Data check failure : object{" + fieldError.getObjectName() + "},field{" + fieldError.getField() +
|
|
|
+ "},errorMessage{" + fieldError.getDefaultMessage() + "}");
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+ }
|
|
|
+ APINoDataResponse apiResponse = new APINoDataResponse();
|
|
|
+ apiResponse.setCode(-1);
|
|
|
+ apiResponse.setMessage("请填写正确信息");
|
|
|
+ return apiResponse;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //仅当方法或类没有标记@NoAPIResponse才自动包装
|
|
|
+ @Override
|
|
|
+ public boolean supports(MethodParameter returnType, Class converterType) {
|
|
|
+ for (Annotation methodAnnotation : returnType.getMethodAnnotations()) {
|
|
|
+ if (methodAnnotation.annotationType() == NoAPIResponse.class) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return returnType.getParameterType() != APIResponse.class && returnType.getParameterType() != APINoDataResponse.class
|
|
|
+ && AnnotationUtils.findAnnotation(returnType.getDeclaringClass(), NoAPIResponse.class) == null;
|
|
|
+ }
|
|
|
+
|
|
|
+ //自动包装外层APIResposne响应
|
|
|
+ @Override
|
|
|
+ public Object beforeBodyWrite(Object body,
|
|
|
+ MethodParameter returnType,
|
|
|
+ MediaType selectedContentType,
|
|
|
+ Class<? extends HttpMessageConverter<?>> selectedConverterType,
|
|
|
+ ServerHttpRequest request, ServerHttpResponse response) {
|
|
|
+
|
|
|
+
|
|
|
+ ResponseMsg responseMsg = returnType.getMethodAnnotation(ResponseMsg.class);
|
|
|
+ String msg = "OK";
|
|
|
+
|
|
|
+ if (null != responseMsg) {
|
|
|
+ msg = responseMsg.value();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (null == body) {
|
|
|
+ APINoDataResponse apiResponse = new APINoDataResponse();
|
|
|
+ apiResponse.setCode(0);
|
|
|
+
|
|
|
+ apiResponse.setMessage(msg);
|
|
|
+ return apiResponse;
|
|
|
+ } else {
|
|
|
+ APIResponse apiResponse = new APIResponse();
|
|
|
+
|
|
|
+ apiResponse.setCode(0);
|
|
|
+ apiResponse.setMessage(msg);
|
|
|
+ apiResponse.setData(body);
|
|
|
+ return apiResponse;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+}
|