Spring Aop 实现日志功能

package com.netauth.api.aoplog;

import java.lang.annotation.*;

/**
 * 
 * <p>
 *  自定义日志接口
 * </p >
 *
 * @date 2022年5月13日
 * @author Tommy
 *
 */
@Target(ElementType.METHOD) //注解放置的目标位置,METHOD是可注解在方法级别上
@Retention(RetentionPolicy.RUNTIME) //注解在哪个阶段执行
@Documented
public @interface OperLog {

    String operModul() default ""; // 操作模块

    String operType() default "";  // 操作类型

    String operDesc() default "";  // 操作说明
}


package com.netauth.api.aoplog;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import com.alibaba.fastjson.JSON;
import com.netauth.entity.user.UserLoginBean;
import com.netauth.utils.currentuser.LoginUserUtil;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

/**
 * 
 * <p>
 *  日志切面实现
 * </p >
 *
 * @date 2022年5月13日
 * @author Tommy
 *
 */
@Aspect
@Component
public class OperLogAspect {

 /**
  * 设置操作日志切入点 记录操作日志 在注解的位置切入代码
  * 描述:哪个方法上带@OperLog注解,就在打印哪个方法的日志
  */
 @Pointcut("@annotation(com.netauth.api.aoplog.OperLog)")
 public void operLogPoinCut() {
 }

 /**
  * 设置操作异常切入点记录异常日志 扫描所有controller包下操作
  */
 @Pointcut("execution(* com.infosec.user..*.*(..))")
 public void operExceptionLogPoinCut() {
 }

 /**
  * 正常返回通知,拦截用户操作日志,连接点正常执行完成后执行, 如果连接点抛出异常,则不会执行
  *
  * @param joinPoint 切入点
  * @param keys      返回结果 此处将result的类型声明为Object,意味着对目标方法的返回值不加限制
  */
 @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);

     Map<String,Object> map = new HashMap<>();
     UserLoginBean localUser = LoginUserUtil.getLoginUserBean(request);
     try {
//         map.put("uuid", UUID.randomUUID().toString().replace("-",""));
         // 从切面织入点处通过反射机制获取织入点处的方法
         MethodSignature signature = (MethodSignature) joinPoint.getSignature();
         // 获取切入点所在的方法
         Method method = signature.getMethod();
         // 获取操作
         OperLog opLog = method.getAnnotation(OperLog.class);
         if (opLog != null) {
             String operModul = opLog.operModul();
             String operType = opLog.operType();
             String operDesc = opLog.operDesc();

             map.put("operModul",operModul);// 操作模块
             map.put("operType",operType);// 操作类型
             map.put("operDesc",operDesc);// 操作描述
         }
         // 获取请求的类名
         String className = joinPoint.getTarget().getClass().getName();
         // 获取请求的方法名
         String methodName = method.getName();
         methodName = className + "." + methodName;
         String username = localUser.getLoginName();
         map.put("loginInfo", username);
         map.put("operMethod",methodName);// 请求方法
         // 请求的参数
//         Map<String, String> rtnMap = converMap(request.getParameterMap());
         // 将参数所在的数组转换成json
//         String params = JSON.toJSONString(rtnMap);
//         map.put("params",params);// 请求参数
         map.put("result",JSON.toJSONString(keys));// 返回结果
         map.put("requestURI",request.getRequestURI());// 请求URI
         //打印结果
         System.out.println("打印操作日志:"+map.toString());
     } 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);

     Map<String,Object> map = new HashMap<>();
     try {
         // 从切面织入点处通过反射机制获取织入点处的方法
         MethodSignature signature = (MethodSignature) joinPoint.getSignature();
         // 获取切入点所在的方法
         Method method = signature.getMethod();
//         map.put("uuid", UUID.randomUUID().toString().replace("-",""));
         // 获取请求的类名
         String className = joinPoint.getTarget().getClass().getName();
         // 获取请求的方法名
         String methodName = method.getName();
         methodName = className + "." + methodName;
         // 请求的参数
         Map<String, String> rtnMap = converMap(request.getParameterMap());
         // 将参数所在的数组转换成json
         String params = JSON.toJSONString(rtnMap);

//         map.put("params",params);// 请求参数
         map.put("methodName",methodName);// 请求方法名
         map.put("excName",e.getClass().getName());
//         map.put("excMessage",stackTraceToString(e.getClass().getName(), e.getMessage(), e.getStackTrace()));// 异常信息
         map.put("requestURI",request.getRequestURI());// 操作URI
         map.put("excCreateTime",new Date());// 发生异常时间
         /**
          * 可以进行入库,只用写个Mapper文件,进行个插入即可;本处只进行打印
          */
         System.out.println("打印异常日志:"+map.toString());
     } catch (Exception e2) {
         e2.printStackTrace();
     }
 }

 /**
  * 转换request 请求参数
  *
  * @param paramMap request获取的参数数组
  */
 public Map<String, String> converMap(Map<String, String[]> paramMap) {
     Map<String, String> rtnMap = new HashMap<String, String>();
     for (String key : paramMap.keySet()) {
         rtnMap.put(key, paramMap.get(key)[0]);
     }
     return rtnMap;
 }

 /**
  * 转换异常信息为字符串
  *
  * @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;
 }
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值