| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- package com.zsElectric.boot.charging.aspect;
- import cn.hutool.core.util.StrUtil;
- import cn.hutool.json.JSONUtil;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import com.zsElectric.boot.charging.entity.ThirdPartyApiLog;
- import com.zsElectric.boot.charging.service.ThirdPartyApiLogService;
- import jakarta.servlet.http.HttpServletRequest;
- import lombok.RequiredArgsConstructor;
- import lombok.extern.slf4j.Slf4j;
- import org.aspectj.lang.ProceedingJoinPoint;
- import org.aspectj.lang.annotation.Around;
- import org.aspectj.lang.annotation.Aspect;
- import org.aspectj.lang.annotation.Pointcut;
- import org.springframework.stereotype.Component;
- import org.springframework.web.context.request.RequestContextHolder;
- import org.springframework.web.context.request.ServletRequestAttributes;
- import java.time.LocalDateTime;
- import java.util.Enumeration;
- import java.util.HashMap;
- import java.util.Map;
- /**
- * 第三方接口日志记录切面
- * 拦截 LinkDataController 和 ChargingBusinessController 的所有方法,自动记录请求和响应日志
- *
- * @author system
- * @since 2025-01-02
- */
- @Slf4j
- @Aspect
- @Component
- @RequiredArgsConstructor
- public class ThirdPartyApiLogAspect {
- private final ThirdPartyApiLogService thirdPartyApiLogService;
- private final ObjectMapper objectMapper;
- /**
- * 定义切入点: LinkDataController 的所有方法
- */
- @Pointcut("execution(* com.zsElectric.boot.charging.controller.LinkDataController.*(..))")
- public void linkDataControllerPointcut() {
- }
- /**
- * 定义切入点: ChargingBusinessController 的所有方法
- */
- @Pointcut("execution(* com.zsElectric.boot.charging.controller.ChargingBusinessController.*(..))")
- public void chargingBusinessControllerPointcut() {
- }
- /**
- * 环绕通知: 记录 LinkDataController 接口日志
- */
- @Around("linkDataControllerPointcut()")
- public Object aroundLinkDataController(ProceedingJoinPoint joinPoint) throws Throwable {
- return recordApiLog(joinPoint, "LinkDataController", 2); // 2-接收推送
- }
- /**
- * 环绕通知: 记录 ChargingBusinessController 接口日志
- */
- @Around("chargingBusinessControllerPointcut()")
- public Object aroundChargingBusinessController(ProceedingJoinPoint joinPoint) throws Throwable {
- return recordApiLog(joinPoint, "ChargingBusinessController", 1); // 1-请求出去
- }
- /**
- * 记录接口日志的通用方法
- */
- private Object recordApiLog(ProceedingJoinPoint joinPoint, String controllerName, Integer logType) throws Throwable {
- long startTime = System.currentTimeMillis();
- ThirdPartyApiLog apiLog = new ThirdPartyApiLog();
-
- // 获取 HttpServletRequest
- ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
- HttpServletRequest request = attributes != null ? attributes.getRequest() : null;
-
- try {
- // 设置基本信息
- apiLog.setLogType(logType);
- apiLog.setControllerName(controllerName);
- LocalDateTime now = LocalDateTime.now();
- apiLog.setCreatedTime(now);
- apiLog.setUpdatedTime(now);
-
- if (request != null) {
- // 请求信息
- apiLog.setRequestMethod(request.getMethod());
- apiLog.setRequestUrl(request.getRequestURL().toString());
- apiLog.setInterfaceName(request.getRequestURI());
- apiLog.setClientIp(getClientIp(request));
- apiLog.setUserAgent(request.getHeader("User-Agent"));
-
- // 请求头
- apiLog.setRequestHeaders(getRequestHeaders(request));
-
- // 请求参数
- Map<String, String[]> parameterMap = request.getParameterMap();
- if (!parameterMap.isEmpty()) {
- apiLog.setRequestParams(objectMapper.writeValueAsString(parameterMap));
- }
-
- // 请求体(从切点参数中获取)
- Object[] args = joinPoint.getArgs();
- if (args != null && args.length > 0) {
- for (Object arg : args) {
- if (arg != null && !(arg instanceof HttpServletRequest) && !(arg instanceof jakarta.servlet.http.HttpServletResponse)) {
- apiLog.setRequestBody(objectMapper.writeValueAsString(arg));
-
- // 尝试提取业务字段
- extractBusinessFields(arg, apiLog);
- break;
- }
- }
- }
- }
-
- // 执行目标方法
- Object result = joinPoint.proceed();
-
- // 记录响应
- long endTime = System.currentTimeMillis();
- apiLog.setResponseTime(endTime - startTime);
- apiLog.setResponseStatus(200);
- apiLog.setIsSuccess(1);
-
- if (result != null) {
- apiLog.setResponseBody(objectMapper.writeValueAsString(result));
- }
-
- // 异步保存日志
- thirdPartyApiLogService.saveLogAsync(apiLog);
-
- return result;
-
- } catch (Exception e) {
- // 记录异常
- long endTime = System.currentTimeMillis();
- apiLog.setResponseTime(endTime - startTime);
- apiLog.setResponseStatus(500);
- apiLog.setIsSuccess(0);
- apiLog.setErrorMessage(e.getMessage());
-
- // 异步保存日志
- thirdPartyApiLogService.saveLogAsync(apiLog);
-
- throw e;
- }
- }
- /**
- * 提取业务字段
- */
- private void extractBusinessFields(Object requestBody, ThirdPartyApiLog apiLog) {
- try {
- String json = objectMapper.writeValueAsString(requestBody);
- Map<String, Object> map = objectMapper.readValue(json, Map.class);
-
- // 提取运营商ID
- if (map.containsKey("OperatorID")) {
- apiLog.setOperatorId(String.valueOf(map.get("OperatorID")));
- } else if (map.containsKey("operatorID")) {
- apiLog.setOperatorId(String.valueOf(map.get("operatorID")));
- }
-
- // 提取充电站ID
- if (map.containsKey("StationID")) {
- apiLog.setStationId(String.valueOf(map.get("StationID")));
- } else if (map.containsKey("stationID")) {
- apiLog.setStationId(String.valueOf(map.get("stationID")));
- }
-
- // 提取充电桩ID
- if (map.containsKey("ConnectorID")) {
- apiLog.setConnectorId(String.valueOf(map.get("ConnectorID")));
- } else if (map.containsKey("connectorID")) {
- apiLog.setConnectorId(String.valueOf(map.get("connectorID")));
- }
-
- // 提取业务流水号
- if (map.containsKey("StartChargeSeq")) {
- apiLog.setBusinessSeq(String.valueOf(map.get("StartChargeSeq")));
- } else if (map.containsKey("startChargeSeq")) {
- apiLog.setBusinessSeq(String.valueOf(map.get("startChargeSeq")));
- } else if (map.containsKey("EquipAuthSeq")) {
- apiLog.setBusinessSeq(String.valueOf(map.get("EquipAuthSeq")));
- } else if (map.containsKey("equipAuthSeq")) {
- apiLog.setBusinessSeq(String.valueOf(map.get("equipAuthSeq")));
- } else if (map.containsKey("EquipBizSeq")) {
- apiLog.setBusinessSeq(String.valueOf(map.get("EquipBizSeq")));
- } else if (map.containsKey("equipBizSeq")) {
- apiLog.setBusinessSeq(String.valueOf(map.get("equipBizSeq")));
- }
-
- } catch (Exception e) {
- log.debug("提取业务字段失败: {}", e.getMessage());
- }
- }
- /**
- * 获取请求头信息
- */
- private String getRequestHeaders(HttpServletRequest request) {
- try {
- Map<String, String> headers = new HashMap<>();
- Enumeration<String> headerNames = request.getHeaderNames();
- while (headerNames.hasMoreElements()) {
- String headerName = headerNames.nextElement();
- headers.put(headerName, request.getHeader(headerName));
- }
- return objectMapper.writeValueAsString(headers);
- } catch (Exception e) {
- log.error("获取请求头失败: {}", e.getMessage());
- return null;
- }
- }
- /**
- * 获取客户端真实IP
- */
- private String getClientIp(HttpServletRequest request) {
- String ip = request.getHeader("X-Forwarded-For");
- if (StrUtil.isNotBlank(ip) && !"unknown".equalsIgnoreCase(ip)) {
- // 多次反向代理后会有多个IP值,第一个为真实IP
- int index = ip.indexOf(',');
- if (index != -1) {
- return ip.substring(0, index);
- }
- return ip;
- }
-
- ip = request.getHeader("X-Real-IP");
- if (StrUtil.isNotBlank(ip) && !"unknown".equalsIgnoreCase(ip)) {
- return ip;
- }
-
- return request.getRemoteAddr();
- }
- }
|