package com.dji.sample.log.aspect; import com.alibaba.druid.support.json.JSONUtils; import com.alibaba.fastjson.JSON; import com.aliyuncs.utils.StringUtils; import com.dji.sample.common.model.CustomClaim; import com.dji.sample.common.model.ResponseResult; import com.dji.sample.log.model.entity.SysLogEntity; import com.dji.sample.log.service.ISysLogService; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import javax.servlet.http.HttpServletRequest; import java.io.BufferedReader; import java.io.InputStreamReader; import java.lang.reflect.Method; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; import static com.dji.sample.component.AuthInterceptor.TOKEN_CLAIM; /** * @PROJECT_NAME: iot_drone_api * @DESCRIPTION: 操作日志切面处理类 * @USER: aix * @DATE: 2023/10/17 16:02 */ @Aspect @Component @Slf4j public class LogAspect { @Autowired private ISysLogService sysLogService; /** * 设置操作日志切入点 在注解的位置切入代码 */ @Pointcut("@annotation(com.dji.sample.log.aspect.SysLogAnnotation)") public void operLogPoinCut() { } @AfterReturning(returning = "result", value = "operLogPoinCut()") public void saveOperLog(JoinPoint joinPoint, ResponseResult result) { // 获取RequestAttributes RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); // 从获取RequestAttributes中获取HttpServletRequest的信息 HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST); try { SysLogEntity sysLog = new SysLogEntity(); // 从切面织入点处通过反射机制获取织入点处的方法 MethodSignature signature = (MethodSignature) joinPoint.getSignature(); //获取切入点所在的方法 Method method = signature.getMethod(); //获取操作 SysLogAnnotation annotation = method.getAnnotation(SysLogAnnotation.class); if (annotation != null) { sysLog.setModel(annotation.operModul()); sysLog.setType(annotation.operType()); sysLog.setDescription(annotation.operDesc()); } // 获取请求的类名 String className = joinPoint.getTarget().getClass().getName(); // 获取请求的方法名 String methodName = method.getName(); methodName = className + "." + methodName; sysLog.setMethod(methodName); // 类名.请求方法 //操作用户 CustomClaim customClaim = (CustomClaim)request.getAttribute(TOKEN_CLAIM); sysLog.setUsername(customClaim.getUsername()); String ipAddress = request.getHeader("X-Forwarded-For"); if (ipAddress == null) { ipAddress = request.getRemoteAddr(); } sysLog.setIp(ipAddress); //操作IP sysLog.setUrl(request.getRequestURI()); // 请求URI // 方法请求的参数 Map rtnMap = converMap(request.getParameterMap()); // 将参数所在的数组转换成json String params = JSONUtils.toJSONString(rtnMap); //获取json的请求参数 if (rtnMap == null || rtnMap.size() == 0) { params = getJsonStrByRequest(request); } sysLog.setParams(params); // 请求参数 sysLog.setResult(JSON.toJSONString(result)); sysLogService.saveSysLog(sysLog); } catch (Exception e) { e.printStackTrace(); log.error("日志记录异常,请检查返回值是否统一"); } } /** * 转换request 请求参数 * * @param paramMap request获取的参数数组 */ public Map converMap(Map paramMap) { Map rtnMap = new HashMap<>(); for (String key : paramMap.keySet()) { rtnMap.put(key, paramMap.get(key)[0]); } return rtnMap; } /** * 获取json格式 请求参数 */ public String getJsonStrByRequest(HttpServletRequest request) { String param = null; try { BufferedReader streamReader = new BufferedReader(new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8)); StringBuilder responseStrBuilder = new StringBuilder(); String inputStr; while ((inputStr = streamReader.readLine()) != null) { responseStrBuilder.append(inputStr); } if(!StringUtils.isEmpty(responseStrBuilder)) { param = JSONUtils.toJSONString(responseStrBuilder); } log.info("log请求参数:",param); } catch (Exception e) { e.printStackTrace(); } return param; } }