Przeglądaj źródła

增加异常处理

欧阳劲驰 1 tydzień temu
rodzic
commit
034ac6a089

+ 165 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/exception/GlobalSelfExceptionHandler.java

@@ -0,0 +1,165 @@
+package com.shkpr.service.customgateway.core.exception;
+
+import com.global.base.log.LogLevelFlag;
+import com.global.base.log.LogPrintMgr;
+import com.shkpr.service.customgateway.core.constants.ResponseCode;
+import com.shkpr.service.customgateway.core.domain.ResultResponse;
+import org.apache.catalina.connector.ClientAbortException;
+import org.springframework.beans.ConversionNotSupportedException;
+import org.springframework.beans.TypeMismatchException;
+import org.springframework.http.converter.HttpMessageNotReadableException;
+import org.springframework.http.converter.HttpMessageNotWritableException;
+import org.springframework.stereotype.Component;
+import org.springframework.web.HttpMediaTypeNotAcceptableException;
+import org.springframework.web.HttpRequestMethodNotSupportedException;
+import org.springframework.web.bind.MissingServletRequestParameterException;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+
+/**
+ * Controller的全局异常捕获类
+ * 前置异常增强(在Controller的方法调用之前若有异常进行捕获),处理结果以JSON的形式返回给客服端
+ * 异常增强类型:NullPointerException,RunTimeException,ClassCastException,
+ *          NoSuchMethodException,IOException,IndexOutOfBoundsException
+ *          以及springmvc自定义异常等,如下:
+ * SpringMVC自定义异常对应的status code
+ * Exception                       HTTP Status Code
+ * ConversionNotSupportedException         500 (Internal Server Error)
+ * HttpMessageNotWritableException         500 (Internal Server Error)
+ * HttpMediaTypeNotSupportedException      415 (Unsupported Media Type)
+ * HttpMediaTypeNotAcceptableException     406 (Not Acceptable)
+ * HttpRequestMethodNotSupportedException  405 (Method Not Allowed)
+ * NoSuchRequestHandlingMethodException    404 (Not Found)
+ * TypeMismatchException                   400 (Bad Request)
+ * HttpMessageNotReadableException         400 (Bad Request)
+ * MissingServletRequestParameterException 400 (Bad Request)
+ *
+ */
+@ControllerAdvice
+@Component
+public class GlobalSelfExceptionHandler {
+
+    public static ResultResponse<String> createResParam(String strCode, String strMsg) {
+        ResultResponse<String> resResult = new ResultResponse<String>();
+        resResult.setTimestamp(System.currentTimeMillis());
+        resResult.setRescode(strCode);
+        resResult.setResmsg(strMsg);
+        resResult.setResdata("");
+        return resResult;
+    }
+
+    public static ResultResponse<String> createResParam(String strCode, String strMsg, String strData) {
+        ResultResponse<String> resResult = new ResultResponse<String>();
+        resResult.setTimestamp(System.currentTimeMillis());
+        resResult.setRescode(strCode);
+        resResult.setResmsg(strMsg);
+        resResult.setResdata((strData == null) ? "" : strData);
+        return resResult;
+    }
+
+    //自定义异常
+    @ExceptionHandler(value = SelfException.class)
+    @ResponseBody
+    public ResultResponse<String> jsonErrorHandler(HttpServletRequest req, SelfException ex) throws Exception {
+        LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_WARN
+                , "Self Exception"
+                , "GlobalSelfExceptionHandler"
+                , String.format("url:{%s}, code(%s):{%s}", req.getRequestURI(), ex.getStrErrorCode(), ex.getMessage()));
+        return createResParam(ex.getStrErrorCode(), ex.getMessage(), ex.getStrErrorData());
+    }
+
+    //运行时异常
+    @ExceptionHandler(RuntimeException.class)
+    @ResponseBody
+    public ResultResponse<String> runtimeExceptionHandler(RuntimeException runtimeException) {
+        LogPrintMgr.getInstance().printExceptionObject(LogLevelFlag.LOG_ERROR, runtimeException);
+        return createResParam(ResponseCode.STATUS_SERVER_RUN_ERROR.getCode() + "", ResponseCode.STATUS_SERVER_RUN_ERROR.getMessage());
+    }
+
+    //空指针异常
+    @ExceptionHandler(NullPointerException.class)
+    @ResponseBody
+    public ResultResponse<String> nullPointerExceptionHandler(NullPointerException ex) {
+        LogPrintMgr.getInstance().printExceptionObject(LogLevelFlag.LOG_ERROR, ex);
+        return createResParam(ResponseCode.STATUS_NULL_POINT_EXCEPTION.getCode() + "", ResponseCode.STATUS_NULL_POINT_EXCEPTION.getMessage());
+    }
+
+    //类型转换异常
+    @ExceptionHandler(ClassCastException.class)
+    @ResponseBody
+    public ResultResponse<String> classCastExceptionHandler(ClassCastException ex) {
+        LogPrintMgr.getInstance().printExceptionObject(LogLevelFlag.LOG_ERROR, ex);
+        return createResParam(ResponseCode.STATUS_ERROR_DATA_TYPE.getCode() + "", ResponseCode.STATUS_ERROR_DATA_TYPE.getMessage());
+    }
+
+    //IO异常
+    @ExceptionHandler({IOException.class, ClientAbortException.class})
+    @ResponseBody
+    public ResultResponse<String> iOExceptionHandler() {
+        return createResParam(ResponseCode.STATUS_IO_EXCEPTION.getCode() + "", ResponseCode.STATUS_IO_EXCEPTION.getMessage());
+    }
+
+    //未知方法异常
+    @ExceptionHandler(NoSuchMethodException.class)
+    @ResponseBody
+    public ResultResponse<String> noSuchMethodExceptionHandler(NoSuchMethodException ex) {
+        return createResParam(ResponseCode.STATUS_NO_SUCH_METHOD.getCode() + "", ResponseCode.STATUS_NO_SUCH_METHOD.getMessage());
+    }
+
+    //数组越界异常
+    @ExceptionHandler(IndexOutOfBoundsException.class)
+    @ResponseBody
+    public ResultResponse<String> indexOutOfBoundsExceptionHandler(IndexOutOfBoundsException ex) {
+        LogPrintMgr.getInstance().printExceptionObject(LogLevelFlag.LOG_ERROR, ex);
+        return createResParam(ResponseCode.STATUS_INDEX_OUT_OF_BOUNDS.getCode() + "", ResponseCode.STATUS_INDEX_OUT_OF_BOUNDS.getMessage());
+    }
+
+    //400错误
+    @ExceptionHandler({HttpMessageNotReadableException.class})
+    @ResponseBody
+    public ResultResponse<String> requestNotReadable(HttpMessageNotReadableException ex) {
+        return createResParam(ResponseCode.STATUS_BAD_REQUEST.getCode() + "", "Request not readable, please check [URI or Param].");
+    }
+
+    //400错误
+    @ExceptionHandler({TypeMismatchException.class})
+    @ResponseBody
+    public ResultResponse<String> requestTypeMismatch(TypeMismatchException ex) {
+        return createResParam(ResponseCode.STATUS_BAD_REQUEST.getCode() + "", "Type mismatch exception, please check [URI or Param].");
+    }
+
+    //400错误
+    @ExceptionHandler({MissingServletRequestParameterException.class})
+    @ResponseBody
+    public ResultResponse<String> requestMissingServletRequest(MissingServletRequestParameterException ex) {
+        return createResParam(ResponseCode.STATUS_BAD_REQUEST.getCode() + "", "Missing servlet request, please check [URI or Param].");
+    }
+
+    //405错误
+    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
+    @ResponseBody
+    public ResultResponse<String> request405() {
+        return createResParam(ResponseCode.STATUS_METHOD_NOT_ALLOWED.getCode() + ""
+                , ResponseCode.STATUS_METHOD_NOT_ALLOWED.getMessage());
+    }
+
+    //406错误
+    @ExceptionHandler({HttpMediaTypeNotAcceptableException.class})
+    @ResponseBody
+    public ResultResponse<String> request406() {
+        return createResParam(ResponseCode.STATUS_HTTP_TYPE_NOT_ACCEPTABLE.getCode() + ""
+                , ResponseCode.STATUS_HTTP_TYPE_NOT_ACCEPTABLE.getMessage() + "Please check [URI or Param].");
+    }
+
+    //500错误
+    @ExceptionHandler({ConversionNotSupportedException.class, HttpMessageNotWritableException.class})
+    @ResponseBody
+    public ResultResponse<String> server500(RuntimeException runtimeException) {
+        return createResParam(ResponseCode.STATUS_HTTP_TYPE_NOT_ACCEPTABLE.getCode() + ""
+                , ResponseCode.STATUS_HTTP_TYPE_NOT_ACCEPTABLE.getMessage() + "Please check [URI or Param].");
+    }
+}

+ 9 - 5
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/utils/CallingUtil.java

@@ -6,9 +6,11 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import com.global.base.log.LogLevelFlag;
 import com.global.base.log.LogPrintMgr;
 import com.shkpr.service.customgateway.core.constants.LogFlagBusiType;
+import com.shkpr.service.customgateway.core.constants.ResponseCode;
 import com.shkpr.service.customgateway.core.domain.PageRequest;
 import com.shkpr.service.customgateway.core.domain.PageResponse;
 import com.shkpr.service.customgateway.core.domain.Result;
+import com.shkpr.service.customgateway.core.exception.SelfException;
 import com.shkpr.service.customgateway.core.properties.CallingProperties;
 import org.apache.http.Header;
 import org.apache.http.client.fluent.Request;
@@ -90,7 +92,8 @@ public class CallingUtil {
      * @return 数据
      */
     public <R extends Result<T>, T> T requestObject(
-            String url, HttpMethod method, Map<String, ?> params, List<Header> headers, TypeReference<R> resultType) {
+            String url, HttpMethod method, Map<String, ?> params, List<Header> headers, TypeReference<R> resultType
+    ) throws SelfException {
         try {
             //发起请求
             Response response = buildRequest(url, method, params)
@@ -98,7 +101,7 @@ public class CallingUtil {
                     .execute();
             //解析结果
             R result = objectMapper.readValue(response.returnContent().asString(StandardCharsets.UTF_8), resultType);
-            if (!result.isOk()) throw new IOException("请求失败: " + result.getMessage());
+            if (!result.isOk()) throw new SelfException(ResponseCode.RESULT_BAD.getCode() + "", result.getMessage());
 
             //返回数据
             return result.getData();
@@ -123,7 +126,8 @@ public class CallingUtil {
      * @return 数据集合
      */
     public <R extends Result<List<T>>, T> List<T> requestList(
-            String url, HttpMethod method, Map<String, ?> params, List<Header> headers, TypeReference<R> resultType) {
+            String url, HttpMethod method, Map<String, ?> params, List<Header> headers, TypeReference<R> resultType
+    ) throws SelfException {
         return requestObject(url, method, params, headers, resultType);
     }
 
@@ -144,7 +148,7 @@ public class CallingUtil {
             String url, HttpMethod method, TypeReference<R> resultType,
             Function<Pageable, Map<String, String>> onGenerateParams,
             Function<Map<String, String>, List<Header>> onGenerateHeaders
-    ) {
+    ) throws SelfException {
         //数据集合
         List<T> dates = new ArrayList<>();
         //分页请求
@@ -166,7 +170,7 @@ public class CallingUtil {
 
                 //解析结果
                 R result = objectMapper.readValue(response.returnContent().toString(), resultType);
-                if (!result.isOk()) throw new IOException("请求失败: " + result.getMessage());
+                if (!result.isOk()) throw new SelfException(ResponseCode.RESULT_BAD.getCode() + "", result.getMessage());
 
                 //解析当前页,并存入数据
                 P page = result.getData();

+ 14 - 5
custom-gateway-zhscada/src/main/java/com/shkpr/service/customgateway/zhscada/components/DataCollector.java

@@ -7,6 +7,7 @@ import com.shkpr.service.customgateway.core.components.DeviceRegistry;
 import com.shkpr.service.customgateway.core.constants.LogFlagBusiType;
 import com.shkpr.service.customgateway.core.domain.Device;
 import com.shkpr.service.customgateway.core.domain.DeviceTag;
+import com.shkpr.service.customgateway.core.exception.SelfException;
 import com.shkpr.service.customgateway.core.properties.CallingProperties;
 import com.shkpr.service.customgateway.core.utils.CallingUtil;
 import com.shkpr.service.customgateway.core.utils.InfluxDbUtil;
@@ -80,12 +81,20 @@ public class DataCollector {
             //参数
             Map<String, Object> params = ScadaPlatformMetadata.getRealTimeDataParams(Collections.singletonList(device));
             //请求结果项
-            List<ScadaPlatformData> items = callingUtil.requestList(url, HttpMethod.GET, params, Collections.emptyList(),
-                    new TypeReference<ScadaPlatformDataResult<List<ScadaPlatformData>>>() {
-                    });
+            List<ScadaPlatformData> items;
+            try {
+                items = callingUtil.requestList(url, HttpMethod.GET, params, Collections.emptyList(),
+                        new TypeReference<ScadaPlatformDataResult<List<ScadaPlatformData>>>() {
+                        });
+                LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, BIZ_TYPE, CLASS_NAME
+                        , String.format("拉取数据成功,数据量:%d", items.size()));
+            } catch (SelfException e) {
+                LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR, BIZ_TYPE, CLASS_NAME
+                        , String.format("拉取数据失败 error:%s", e)
+                );
+                continue;
+            }
 
-            LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, BIZ_TYPE, CLASS_NAME
-                    , String.format("拉取数据成功,数据量:%d", items.size()));
             allItems.addAll(items);
         }
 

+ 14 - 6
custom-gateway-zhscada/src/main/java/com/shkpr/service/customgateway/zhscada/components/InfoSynchronizer.java

@@ -6,6 +6,7 @@ import com.global.base.log.LogLevelFlag;
 import com.global.base.log.LogPrintMgr;
 import com.shkpr.service.customgateway.core.constants.LogFlagBusiType;
 import com.shkpr.service.customgateway.core.domain.po.DeviceTags;
+import com.shkpr.service.customgateway.core.exception.SelfException;
 import com.shkpr.service.customgateway.core.properties.CallingProperties;
 import com.shkpr.service.customgateway.core.service.DeviceTagsService;
 import com.shkpr.service.customgateway.core.utils.CallingUtil;
@@ -66,12 +67,19 @@ public class InfoSynchronizer {
         Map<String, Object> params = Collections.singletonMap(ScadaPlatformMetadata.Params.PROJECT_NAME,
                 ScadaPlatformMetadata.DefaultValues.PROJECT_NAME);
         //请求结果项
-        List<ScadaPlatformVariables> items = callingUtil.requestList(url, HttpMethod.GET, params, Collections.emptyList(),
-                new TypeReference<ScadaPlatformVariablesResult<List<ScadaPlatformVariables>>>() {
-                });
-        LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, BIZ_TYPE, CLASS_NAME
-                , String.format("拉取标签成功,数据量:%d", items.size()));
-
+        List<ScadaPlatformVariables> items;
+        try {
+            items = callingUtil.requestList(url, HttpMethod.GET, params, Collections.emptyList(),
+                    new TypeReference<ScadaPlatformVariablesResult<List<ScadaPlatformVariables>>>() {
+                    });
+            LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, BIZ_TYPE, CLASS_NAME
+                    , String.format("拉取标签成功,数据量:%d", items.size()));
+        } catch (SelfException e) {
+            items = Collections.emptyList();
+            LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR, BIZ_TYPE, CLASS_NAME
+                    , String.format("拉取标签失败 error:%s", e)
+            );
+        }
 
         //转换采集标签对象
         List<DeviceTags> dates = items.stream()

+ 14 - 5
custom-gateway-zydma/src/main/java/com/shkpr/service/customgateway/zydma/components/DataCollector.java

@@ -9,6 +9,7 @@ import com.shkpr.service.customgateway.core.constants.LogFlagBusiType;
 import com.shkpr.service.customgateway.core.domain.Device;
 import com.shkpr.service.customgateway.core.domain.DeviceTag;
 import com.shkpr.service.customgateway.core.domain.IntegrationKey;
+import com.shkpr.service.customgateway.core.exception.SelfException;
 import com.shkpr.service.customgateway.core.properties.CallingProperties;
 import com.shkpr.service.customgateway.core.utils.CallingUtil;
 import com.shkpr.service.customgateway.core.utils.InfluxDbUtil;
@@ -112,11 +113,19 @@ public class DataCollector {
             //参数
             Map<String, Object> params = IotPlatformMetadata.getHistoryDataParams(deviceMapping, beginTime, endTime);
             //请求结果项
-            List<IotPlatformData> items = callingUtil.requestList(url, HttpMethod.POST, params, headers,
-                    new TypeReference<IotPlatformResult<List<IotPlatformData>>>() {
-                    });
-            LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, BIZ_TYPE, CLASS_NAME
-                    , String.format("拉取数据成功,数据量:%d", items.size()));
+            List<IotPlatformData> items;
+            try {
+                     items = callingUtil.requestList(url, HttpMethod.POST, params, headers,
+                        new TypeReference<IotPlatformResult<List<IotPlatformData>>>() {
+                        });
+                LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, BIZ_TYPE, CLASS_NAME
+                        , String.format("拉取数据成功,数据量:%d", items.size()));
+            } catch (SelfException e) {
+                LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR, BIZ_TYPE, CLASS_NAME
+                        , String.format("拉取数据失败 error:%s", e)
+                );
+                continue;
+            }
 
             //按设备(远传id)分组
             Map<String, List<IotPlatformData>> snGroup = items.stream()

+ 28 - 19
custom-gateway-zydma/src/main/java/com/shkpr/service/customgateway/zydma/components/InfoSynchronizer.java

@@ -5,6 +5,7 @@ import com.global.base.log.LogLevelFlag;
 import com.global.base.log.LogPrintMgr;
 import com.shkpr.service.customgateway.core.constants.LogFlagBusiType;
 import com.shkpr.service.customgateway.core.domain.IntegrationKey;
+import com.shkpr.service.customgateway.core.exception.SelfException;
 import com.shkpr.service.customgateway.core.properties.CallingProperties;
 import com.shkpr.service.customgateway.core.utils.CallingUtil;
 import com.shkpr.service.customgateway.zydma.constants.MiddlePlatformMetadata;
@@ -19,6 +20,7 @@ import org.springframework.http.HttpMethod;
 import org.springframework.stereotype.Component;
 
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -35,8 +37,8 @@ public class InfoSynchronizer {
     /**
      * log
      */
-    private static final String mStrClassName = "InfoSynchronizer";
-    private static final String mBizType = LogFlagBusiType.BUSI_ALL.toStrValue();
+    private static final String CLASS_NAME = "InfoSynchronizer";
+    private static final String BIZ_TYPE = LogFlagBusiType.BUSI_ALL.toStrValue();
 
     final
     CallingProperties callingProperties;
@@ -57,7 +59,7 @@ public class InfoSynchronizer {
      * @param userId 用户ID
      */
     public void syncUserInfo(Long userId) {
-        LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBizType, mStrClassName
+        LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, BIZ_TYPE, CLASS_NAME
                 , "开始同步用户信息,开始滚动拉取数据");
         long begin = System.currentTimeMillis();
 
@@ -77,7 +79,7 @@ public class InfoSynchronizer {
         //批量写入用户
         Boolean upserted = personnelInfoService.upsertAll(dates);
         long end = System.currentTimeMillis();
-        LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBizType, mStrClassName
+        LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, BIZ_TYPE, CLASS_NAME
                 , String.format(
                         "结束执行同步用户信息,迁移状态:%s,用时(毫秒):%d"
                         , upserted
@@ -96,20 +98,27 @@ public class InfoSynchronizer {
         //请求地址
         String url = endpoint.getUrl() + MiddlePlatformMetadata.Uri.GET_USERS;
         //请求获取用户
-        return callingUtil.requestScroll(url, HttpMethod.GET,
-                new TypeReference<MiddlePlatformResult<MiddlePlatformPage<MiddlePlatformUser>>>() {
-                }, pageable -> new HashMap<String, String>() {{
-                    put(MiddlePlatformMetadata.Params.PAGE_NUMBER, pageable.getPageNumber() + "");
-                    put(MiddlePlatformMetadata.Params.PAGE_SIZE, pageable.getPageSize() + "");
-                }}, params -> {
-                    //获取密钥
-                    IntegrationKey key = MiddlePlatformMetadata.getKey(endpoint.getAccessKey(), endpoint.getSecretKey(), params);
-                    //存入请求头
-                    return Arrays.asList(
-                            new BasicHeader(MiddlePlatformMetadata.Headers.APP_KEY, key.getAccessKey()),
-                            new BasicHeader(MiddlePlatformMetadata.Headers.TIMESTAMP, key.getTimestamp() + ""),
-                            new BasicHeader(MiddlePlatformMetadata.Headers.SIGN, key.getSecretKey())
-                    );
-                });
+        try {
+            return callingUtil.requestScroll(url, HttpMethod.GET,
+                    new TypeReference<MiddlePlatformResult<MiddlePlatformPage<MiddlePlatformUser>>>() {
+                    }, pageable -> new HashMap<String, String>() {{
+                        put(MiddlePlatformMetadata.Params.PAGE_NUMBER, pageable.getPageNumber() + "");
+                        put(MiddlePlatformMetadata.Params.PAGE_SIZE, pageable.getPageSize() + "");
+                    }}, params -> {
+                        //获取密钥
+                        IntegrationKey key = MiddlePlatformMetadata.getKey(endpoint.getAccessKey(), endpoint.getSecretKey(), params);
+                        //存入请求头
+                        return Arrays.asList(
+                                new BasicHeader(MiddlePlatformMetadata.Headers.APP_KEY, key.getAccessKey()),
+                                new BasicHeader(MiddlePlatformMetadata.Headers.TIMESTAMP, key.getTimestamp() + ""),
+                                new BasicHeader(MiddlePlatformMetadata.Headers.SIGN, key.getSecretKey())
+                        );
+                    });
+        } catch (SelfException e) {
+            LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR, BIZ_TYPE, CLASS_NAME
+                    , String.format("获取用户失败 error:%s", e)
+            );
+            return Collections.emptyList();
+        }
     }
 }