package com.jilongda.manage.log; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.jilongda.manage.service.OperLogService; import com.jilongda.common.log.OperationLog; import com.jilongda.common.log.ParamParser; import com.jilongda.common.model.OperLog; import com.jilongda.common.utils.IPUtil; import com.jilongda.common.utils.SpringContextUtils; import com.jilongda.manage.security.SecurityUserDetails; import com.jilongda.manage.security.SysUserDetailsService; 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.security.authentication.AnonymousAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.time.LocalDateTime; import java.util.HashMap; import java.util.Map; /** * 切面处理类,操作日志记录处理 * * @author xiaochen * @date 2021/12/21 */ @Aspect @Component public class OperationLogAspect { @Autowired private OperLogService operLogService; @Autowired private SysUserDetailsService loadUserDetailsService; /** * 设置操作日志切入点 记录操作日志 在注解的位置切入代码 */ @Pointcut("@annotation(com.jilongda.common.log.OperationLog)") public void operLogPoinCut() { } /** * 正常返回通知,拦截用户操作日志,连接点正常执行完成后执行, 如果连接点抛出异常,则不会执行 * * @param joinPoint 切入点 * @param keys 返回结果 */ @AfterReturning(value = "operLogPoinCut()", returning = "keys") public void saveOperLog(JoinPoint joinPoint, Object keys) { // 获取RequestAttributes RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); // 从获取RequestAttributes中获取HttpServletRequest的信息 // HttpServletRequest request = (HttpServletRequest) requestAttributes // .resolveReference(RequestAttributes.REFERENCE_REQUEST); HttpServletRequest request = SpringContextUtils.getHttpServletRequest(); OperLog operlog = new OperLog(); StringBuilder sb = new StringBuilder(); try { // 从切面织入点处通过反射机制获取织入点处的方法 MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // 获取切入点所在的方法 Method method = signature.getMethod(); // 获取操作 OperationLog opLog = method.getAnnotation(OperationLog.class); if (opLog != null) { String operModul = opLog.operModul(); String operType = opLog.operType(); String operDesc = opLog.operDesc(); operlog.setOperModel(operModul); // 操作模块 operlog.setOperType(operType); // 操作类型 operlog.setOperDesc(operDesc); // 操作描述 } // 获取请求的类名 String className = joinPoint.getTarget().getClass().getName(); // 获取请求的方法名 String methodName = method.getName(); methodName = className + "." + methodName; operlog.setOperMethod(methodName); // 请求方法 // 请求的参数 // 请求的参数 // 操作简述绑定参数 Object paramParserObj = null; String requestArgs; Parameter[] parameters = method.getParameters(); if (parameters != null && parameters.length > 0) { for (int i = 0; i < parameters.length; i++) { ParamParser an = parameters[i].getDeclaredAnnotation(ParamParser.class); if (an != null) { paramParserObj = an.value(); break; } } } // 不止一个参数 if (paramParserObj != null) { requestArgs = sb.append(":").append(paramParserObj).toString(); } else { requestArgs = JSONObject.toJSONString(joinPoint.getArgs()); } operlog.setOperReqParam(requestArgs); // 获取当前登录用户信息 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String userName = null; if (!(authentication instanceof AnonymousAuthenticationToken)) { userName = authentication.getName(); } if (StringUtils.hasLength(userName)) { // 通过用户名查询该账号信息 SecurityUserDetails userDetails = loadUserDetailsService.loadUserByUsername(userName); operlog.setOperUserName(userDetails.getNickName()); // 请求用户名称 operlog.setOperAccount(userDetails.getAccount()); // 请求账号 } // operlog.setOperRespParam(JSON.toJSONString(keys)); // 返回结果 // operlog.setOperUserId(UserShiroUtil.getCurrentUserLoginName()); // 请求用户ID operlog.setOperIp(IPUtil.getIpAddress(request)); // 请求IP operlog.setOperUri(request.getRequestURI()); // 请求URI operlog.setOperOperationTime(LocalDateTime.now()); // 创建时间 // operlog.setOperVer(operVer); // 操作版本 operLogService.save(operlog); } catch (Exception e) { e.printStackTrace(); } } /** * 异常返回通知,用于拦截异常日志信息 连接点抛出异常后执行 * * @param joinPoint 切入点 * @param e 异常信息 */ /*@AfterThrowing(pointcut = "operExceptionLogPoinCut()", throwing = "e") public void saveExceptionLog(JoinPoint joinPoint, Throwable e) { // 获取RequestAttributes RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); // 从获取RequestAttributes中获取HttpServletRequest的信息 HttpServletRequest request = (HttpServletRequest) requestAttributes .resolveReference(RequestAttributes.REFERENCE_REQUEST); ExceptionLog excepLog = new ExceptionLog(); try { // 从切面织入点处通过反射机制获取织入点处的方法 MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // 获取切入点所在的方法 Method method = signature.getMethod(); excepLog.setExcId(UuidUtil.get32UUID()); // 获取请求的类名 String className = joinPoint.getTarget().getClass().getName(); // 获取请求的方法名 String methodName = method.getName(); methodName = className + "." + methodName; // 请求的参数 Map rtnMap = converMap(request.getParameterMap()); // 将参数所在的数组转换成json String params = JSON.toJSONString(rtnMap); excepLog.setExcRequParam(params); // 请求参数 excepLog.setOperMethod(methodName); // 请求方法名 excepLog.setExcName(e.getClass().getName()); // 异常名称 excepLog.setExcMessage(stackTraceToString(e.getClass().getName(), e.getMessage(), e.getStackTrace())); // 异常信息 excepLog.setOperUserId(UserShiroUtil.getCurrentUserLoginName()); // 操作员ID excepLog.setOperUserName(UserShiroUtil.getCurrentUserName()); // 操作员名称 excepLog.setOperUri(request.getRequestURI()); // 操作URI excepLog.setOperIp(IPUtil.getRemortIP(request)); // 操作员IP excepLog.setOperVer(operVer); // 操作版本号 excepLog.setOperCreateTime(new Date()); // 发生异常时间 exceptionLogService.insert(excepLog); } catch (Exception e2) { e2.printStackTrace(); } }*/ /** * 转换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格式 * * @param request * @return * @throws ServletException * @throws IOException */ public Map getJSON(HttpServletRequest request) throws ServletException, IOException { BufferedReader streamReader = new BufferedReader(new InputStreamReader(request.getInputStream(), "UTF-8")); StringBuilder responseStrBuilder = new StringBuilder(); String inputStr; while ((inputStr = streamReader.readLine()) != null) { responseStrBuilder.append(inputStr); } Map params = JSON.parseObject(responseStrBuilder.toString(), Map.class); return params; } /** * 转换异常信息为字符串 * * @param exceptionName 异常名称 * @param exceptionMessage 异常信息 * @param elements 堆栈信息 */ public String stackTraceToString(String exceptionName, String exceptionMessage, StackTraceElement[] elements) { StringBuffer strbuff = new StringBuffer(); for (StackTraceElement stet : elements) { strbuff.append(stet + "\n"); } String message = exceptionName + ":" + exceptionMessage + "\n\t" + strbuff.toString(); return message; } }