自定义注解+AOP实现请求日志记录

本文介绍了一种在SSM环境中使用自定义注解和AOP实现API监控的方法,包括记录请求链接、类型、IP及描述,适用于客户端请求的全面监控。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求描述:

在所有的接口中记录客户端发送过来的请求。记录信息包括:

  1. 请求链接
  2. 请求类型
  3. 请求IP
  4. 请求描述等…

实现效果:
在这里插入图片描述


1、自定义注解
package com.nys.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 自定义注解-API监控
 * @author nysheng
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiEyes {
    String value() default "";
}


2、AOP实现
package com.nys.aop;

import com.nys.annotation.ApiEyes;
import com.nys.utils.IPUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * AOP实现-切入所有被注解@ApiEyes标记的方法
 * @author nysheng
 */
@Aspect
@Component
public class MyAspect {
    //日志记录
    private Logger logger= LoggerFactory.getLogger(MyAspect.class);
    //切入点配置为注解@ApiEyes
    @Pointcut("@annotation(com.nys.annotation.ApiEyes)")
    public void apiEyes(){}
    /**
     * 环绕通知
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around("apiEyes()")
    public Object before(ProceedingJoinPoint joinPoint) throws Throwable {
        //1.请求开始
        logger.info("=====请求进入======");
        long start=System.currentTimeMillis();
        //2.获取注解对象
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature=(MethodSignature)signature;
        Method method = methodSignature.getMethod();
        ApiEyes apiEyes = method.getAnnotation(ApiEyes.class);
        //3.获取注解属性
        String value = apiEyes.value();
        //4.获取request
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        //5.记录日志
        logger.info("请求链接:{}",request.getRequestURL().toString());
        logger.info("请求类型:{}",request.getMethod());
        logger.info("请求IP:{}",IPUtil.getIpAddress(request));
        logger.info("请求描述:{}",value);
        //6.执行
        Object object=joinPoint.proceed();
        //7.请求结束
        long end=System.currentTimeMillis();
        logger.info("请求用时:{}",(end-start));
        logger.info("=====请求结束======");
        return object;
    }
}

3、获取IP
package com.nys.utils;
import javax.servlet.http.HttpServletRequest;

/**
 * IP工具类,获取客户端请求的真实IP地址
 * @author nysheng
 */
public class IPUtil {
    public static String getIpAddress(HttpServletRequest request) {
        String ip = null;
        //X-Forwarded-For:Squid 服务代理
        String ipAddresses = request.getHeader("X-Forwarded-For");
        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            //Proxy-Client-IP:apache 服务代理
            ipAddresses = request.getHeader("Proxy-Client-IP");
        }
        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            //WL-Proxy-Client-IP:weblogic 服务代理
            ipAddresses = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            //HTTP_CLIENT_IP:有些代理服务器
            ipAddresses = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            //X-Real-IP:nginx服务代理
            ipAddresses = request.getHeader("X-Real-IP");
        }

        //有些网络通过多层代理,那么获取到的ip就会有多个,一般都是通过逗号(,)分割开来,并且第一个ip为客户端的真实IP
        if (ipAddresses != null && ipAddresses.length() != 0) {
            ip = ipAddresses.split(",")[0];
        }

        //还是不能获取到,最后再通过request.getRemoteAddr();获取
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            ip = request.getRemoteAddr();
        }
        return ip.equals("0:0:0:0:0:0:0:1")?"127.0.0.1":ip;
    }
}


4、使用方法

直接在要监听的方法上加上@ApiEyes注解即可
在这里插入图片描述


注:SSM环境需要在Spring配置文件中加入

<context:component-scan base-package="com.nys"/>
<!-- 启用 aspectj 方式 AOP-->
<aop:aspectj-autoproxy proxy-target-class="true" />

相关:
https://mp.weixin.qq.com/s/zjn_lrnSLmswqH-Txvr5eg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值