|
@@ -1,9 +1,13 @@
|
|
|
package com.yonge.cooleshow.mall.common.exception;
|
|
|
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
import com.yonge.cooleshow.mall.common.api.CommonResult;
|
|
|
-import com.yonge.cooleshow.mall.common.api.IErrorCode;
|
|
|
import com.yonge.toolset.base.exception.BizException;
|
|
|
-import org.springframework.http.HttpStatus;
|
|
|
+import com.yonge.toolset.utils.http.HttpUtil;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.codec.binary.Base64;
|
|
|
+import org.apache.commons.lang3.exception.ExceptionUtils;
|
|
|
import org.springframework.validation.BindException;
|
|
|
import org.springframework.validation.BindingResult;
|
|
|
import org.springframework.validation.FieldError;
|
|
@@ -11,11 +15,27 @@ import org.springframework.web.bind.MethodArgumentNotValidException;
|
|
|
import org.springframework.web.bind.annotation.ControllerAdvice;
|
|
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
|
|
import org.springframework.web.bind.annotation.ResponseBody;
|
|
|
+import org.springframework.web.context.request.RequestContextHolder;
|
|
|
+import org.springframework.web.context.request.ServletRequestAttributes;
|
|
|
+
|
|
|
+import javax.crypto.Mac;
|
|
|
+import javax.crypto.spec.SecretKeySpec;
|
|
|
+import javax.servlet.http.HttpServletRequest;
|
|
|
+import java.io.BufferedReader;
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.InputStreamReader;
|
|
|
+import java.net.URLEncoder;
|
|
|
+import java.util.Enumeration;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Objects;
|
|
|
+import java.util.Optional;
|
|
|
|
|
|
/**
|
|
|
* 全局异常处理
|
|
|
* Created by macro on 2020/2/27.
|
|
|
*/
|
|
|
+@Slf4j
|
|
|
@ControllerAdvice
|
|
|
public class GlobalExceptionHandler {
|
|
|
|
|
@@ -39,6 +59,10 @@ public class GlobalExceptionHandler {
|
|
|
message = fieldError.getField()+fieldError.getDefaultMessage();
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ // 发送机器人消息
|
|
|
+ sendDingTalkRobotNotify(e);
|
|
|
+
|
|
|
return CommonResult.validateFailed(message);
|
|
|
}
|
|
|
|
|
@@ -53,6 +77,10 @@ public class GlobalExceptionHandler {
|
|
|
message = fieldError.getField()+fieldError.getDefaultMessage();
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ // 发送机器人消息
|
|
|
+ sendDingTalkRobotNotify(e);
|
|
|
+
|
|
|
return CommonResult.validateFailed(message);
|
|
|
}
|
|
|
|
|
@@ -62,4 +90,141 @@ public class GlobalExceptionHandler {
|
|
|
public CommonResult handleBizException(BizException e) {
|
|
|
return CommonResult.failed(e.getMessage());
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取异常信息
|
|
|
+ * @param ex Throwable
|
|
|
+ * @return Throwable
|
|
|
+ */
|
|
|
+ private static Throwable getThrowable(Throwable ex) {
|
|
|
+ return Optional.ofNullable(ExceptionUtils.getRootCause(ex)).orElse(ex);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 机器人发送消息
|
|
|
+ * @param e Throwable
|
|
|
+ */
|
|
|
+ private void sendDingTalkRobotNotify(Throwable e) {
|
|
|
+ try {
|
|
|
+
|
|
|
+ ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
|
|
+ if (Objects.nonNull(attributes)) {
|
|
|
+
|
|
|
+ // 机器人通知消息
|
|
|
+ String robotMessage = getRobotRequestLog(attributes.getRequest());
|
|
|
+
|
|
|
+ Map<String, Object> paramMap = new HashMap<>(2);
|
|
|
+ JSONObject jsonObject = new JSONObject();
|
|
|
+ jsonObject.put("content", "系统繁忙请及时处理: " + robotMessage + " " + getThrowable(e));
|
|
|
+ paramMap.put("text", jsonObject.toJSONString());
|
|
|
+ paramMap.put("msgtype", "text");
|
|
|
+ Map<String, String> headers = new HashMap<>(1);
|
|
|
+ headers.put("Content-Type", "application/json");
|
|
|
+ HttpUtil.postForHttps(dingTalkRobotsSecurityParam(), JSON.toJSONString(paramMap), headers);
|
|
|
+
|
|
|
+ }
|
|
|
+ } catch (Exception exception) {
|
|
|
+ log.error("sendDingTalkRobotNotify Error", exception);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 打印异常请求日志
|
|
|
+ * @param request HttpServletRequest
|
|
|
+ * @return String
|
|
|
+ */
|
|
|
+ private String getRobotRequestLog(HttpServletRequest request){
|
|
|
+
|
|
|
+ if (Objects.isNull(request)) {
|
|
|
+ log.warn("getRobotRequestLog request is null");
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
+ // 打印请求日志或执行其他逻辑
|
|
|
+ sb.append("Request URI: ").append(request.getRequestURI());
|
|
|
+
|
|
|
+ // 请求参数
|
|
|
+ Map<String, String> requestParams = getRequestParameters(request);
|
|
|
+ if (!requestParams.isEmpty()) {
|
|
|
+ sb.append(", Request Parameters: ").append(requestParams);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 请求头
|
|
|
+ Map<String, String> requestHeaders = getRequestHeaders(request);
|
|
|
+ if (!requestHeaders.isEmpty()) {
|
|
|
+ sb.append(", Request Headers: ").append(requestHeaders);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 请求消息体
|
|
|
+ String requestBody = getRequestBody(request);
|
|
|
+ if (!requestBody.isEmpty()) {
|
|
|
+ sb.append(", Request JSON: ").append(requestBody);
|
|
|
+ }
|
|
|
+ return sb.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 请求参数
|
|
|
+ * @param request HttpServletRequest
|
|
|
+ * @return Map<String, String>
|
|
|
+ */
|
|
|
+ private Map<String, String> getRequestParameters(HttpServletRequest request) {
|
|
|
+ Map<String, String> params = new HashMap<>();
|
|
|
+ request.getParameterMap().forEach((name, values) -> {
|
|
|
+ if (values.length > 0) {
|
|
|
+ params.put(name, values[0]);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return params;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 请求头
|
|
|
+ * @param request HttpServletRequest
|
|
|
+ * @return Map<String, String>
|
|
|
+ */
|
|
|
+ private Map<String, String> getRequestHeaders(HttpServletRequest request) {
|
|
|
+ Enumeration<String> headerNames = request.getHeaderNames();
|
|
|
+ Map<String, String> headers = new HashMap<>();
|
|
|
+ while (headerNames.hasMoreElements()) {
|
|
|
+ String headerName = headerNames.nextElement();
|
|
|
+ String headerValue = request.getHeader(headerName);
|
|
|
+ headers.put(headerName, headerValue);
|
|
|
+ }
|
|
|
+ return headers;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 请求消息体
|
|
|
+ * @param request HttpServletRequest
|
|
|
+ * @return String
|
|
|
+ */
|
|
|
+ private String getRequestBody(HttpServletRequest request) {
|
|
|
+ StringBuilder requestBody = new StringBuilder();
|
|
|
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()))) {
|
|
|
+ String line;
|
|
|
+ while ((line = reader.readLine()) != null) {
|
|
|
+ requestBody.append(line);
|
|
|
+ }
|
|
|
+ } catch (IOException e) {
|
|
|
+ log.error("robot getRequestBody body: {}", e.getMessage());
|
|
|
+ }
|
|
|
+ return requestBody.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ public String dingTalkRobotsSecurityParam() throws Exception {
|
|
|
+ Long timestamp = System.currentTimeMillis();
|
|
|
+ String secret = "SEC7371152e58a066b358afd9e9cfaad2aee4b46471218f1aeef88d43a401d8e2f2";
|
|
|
+ String stringToSign = timestamp + "\n" + secret;
|
|
|
+ Mac mac = Mac.getInstance("HmacSHA256");
|
|
|
+ mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256"));
|
|
|
+ byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
|
|
|
+ String sign = URLEncoder.encode(new String(Base64.encodeBase64(signData)), "UTF-8");
|
|
|
+ StringBuffer sb = new StringBuffer("https://oapi.dingtalk.com/robot/send?access_token=324dc48b8af4fc21223a5b8fd5d8daa611e106f2711d91abe1d73bce8c5c86b2×tamp=");
|
|
|
+ sb.append(timestamp).append("&sign=").append(sign);
|
|
|
+ return sb.toString();
|
|
|
+ }
|
|
|
}
|