springboot+Aop日志实现

一:首先定义日志切面注解


/**
 *
 * * 自定义操作日志注解
 * @author zhoupengwei
 */
@Target(ElementType.METHOD) //注解放置的目标位置,METHOD是可注解在方法级别上
@Retention(RetentionPolicy.RUNTIME) //注解在哪个阶段执行
@Documented
public @interface OperLog {
    String operModul() default ""; // 操作模块

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

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

 

二:日志切面处理类

/**
 * * 自定义操作日志注解
 *
 * @author zhoupengwei
 */
@Aspect
@Component
public class OperLogAspect {
    @Resource
    OperLogDAO operLogDAO;


    @Resource
    TokenUtils tokenUtils;

    /**
     * 设置操作日志切入点 记录操作日志 在注解的位置切入代码
     */
    @Pointcut("@annotation(com.cfht.demo.aop.OperLog)")
    public void operLogPoinCut() {
    }

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

    @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);

        OperLogEntity operlog = new OperLogEntity();
        try {
            //  operlog.setOperId(UuidUtil.get32UUID()); // 主键ID

            // 从切面织入点处通过反射机制获取织入点处的方法
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            // 获取切入点所在的方法
            Method method = signature.getMethod();
            // 获取操作
            OperLog opLog = method.getAnnotation(OperLog.class);
            if (opLog != null) {

                operlog.setOperModel(opLog.operModul()); // 操作模块
                operlog.setOperType(opLog.operType()); // 操作类型
                operlog.setOperDesc(opLog.operDesc()); // 操作描述
            }
            // 获取请求的类名
            String className = joinPoint.getTarget().getClass().getName();
            // 获取请求的方法名
            String methodName = method.getName();
            methodName = className + "." + methodName;
            operlog.setOperMethod(methodName); // 请求方法

            // 请求的参数
            Map<String, String> rtnMap = converMap(request.getParameterMap());
            // 将参数所在的数组转换成json
            String params = JSON.toJSONString(rtnMap);
            if (!"".equals(request.getHeader("token")) && null != request.getHeader("token")) {
                Claims claims1 = tokenUtils.getTokenUser(request.getHeader("token"));
                if (null != claims1) {
                    operlog.setOperUserId(claims1.getId()); // 请求用户ID
                    operlog.setOperUserName(claims1.get("sub").toString()); // 请求用户名称
                    operlog.setOperIp(getIpAddress(request)); // 请求IP
                }
            }

            operlog.setOperRequParam(params); // 请求参数
            operlog.setOperRespParam(JSON.toJSONString(keys)); // 返回结果

            operlog.setOperUrl(request.getRequestURI()); // 请求URI
            operlog.setDataType("1");  //1 正常日常  0:异常日志
            operLogDAO.insert(operlog);
        } catch (Exception e) {
            e.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;
    }


    /***
     * 获取客户端IP地址
     *
     */

    private String getIpAddress(HttpServletRequest request) {
        String ipAddress = null;
        try {
            ipAddress = request.getHeader("x-forwarded-for");
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getRemoteAddr();
                if (ipAddress.equals("127.0.0.1")) {
                    // 根据网卡取本机配置的IP
                    InetAddress inet = null;
                    try {
                        inet = InetAddress.getLocalHost();
                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                    }
                    ipAddress = inet.getHostAddress();
                }
            }
            // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
            if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length()
                // = 15
                if (ipAddress.indexOf(",") > 0) {
                    ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
                }
            }
        } catch (Exception e) {
            ipAddress = "";
        }
        // ipAddress = this.getRequest().getRemoteAddr();

        return ipAddress;


    }
}

三:创建日志实体类、数据库新建log表

/**
* <p>Description: [入参]</p>
* Created on 2021-04-25 09:58:23
*
* @author zhoupengwei
*/
@Data
@ApiModel("入参")
public class OperLogVo{

        /**
        * 数据类型
        */
        @ApiModelProperty(value = "数据类型",name = "dataType")
        private String dataType;

        /**
        * 异常信息
        */
        @ApiModelProperty(value = "异常信息",name = "excMessage")
        private String excMessage;

        /**
        * 异常名称
        */
        @ApiModelProperty(value = "异常名称",name = "excName")
        private String excName;

        /**
        * 日志id
        */
        @ApiModelProperty(value = "日志id",name = "id")
        private Long id;

        /**
        * 操作描述
        */
        @ApiModelProperty(value = "操作描述",name = "operDesc")
        private String operDesc;

        /**
        * 操作ip
        */
        @ApiModelProperty(value = "操作ip",name = "operIp")
        private String operIp;

        /**
        * 操作方法
        */
        @ApiModelProperty(value = "操作方法",name = "operMethod")
        private String operMethod;

        /**
        * 功能模块
        */
        @ApiModelProperty(value = "功能模块",name = "operModel")
        private String operModel;

        /**
        * 请求参数
        */
        @ApiModelProperty(value = "请求参数",name = "operRequParam")
        private String operRequParam;

        /**
        * 返回参数
        */
        @ApiModelProperty(value = "返回参数",name = "operRespParam")
        private String operRespParam;

        /**
        * 操作类型
        */
        @ApiModelProperty(value = "操作类型",name = "operType")
        private String operType;

        /**
        * 操作地址
        */
        @ApiModelProperty(value = "操作地址",name = "operUrl")
        private String operUrl;

        /**
        * 人员id
        */
        @ApiModelProperty(value = "人员id",name = "operUserId")
        private String operUserId;

        /**
        * 人员name
        */
        @ApiModelProperty(value = "人员name",name = "operUserName")
        private String operUserName;

}

 

四:在控制层添加日志注解

  @UserLoginToken
    @GetMapping("/getMessage")
    @OperLog(operModul = "用户管理", operType = "TEST", operDesc = "测试接口")

    public String getMessage(StringBuffer token) {
        return "你已通过验证";
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值