AOP拦截请求获取请求参数和请求方法,以及请求耗时ms

本文介绍了两种在Spring AOP中实现控制器层请求日志记录的方法。方法一通过遍历注解获取请求路径,方法二直接从HttpServletRequest获取请求URL。这两种方式都在环绕通知中记录了请求方法和URL,并在异常时打印异常通知。作者推荐使用方法二,因其更简洁高效。
摘要由CSDN通过智能技术生成

方法一:

package com.live.log.aspect;

public enum AnnotationTypeEnum {

    REQUEST_MAPPING("RequestMapping"),
    POST_MAPPING("PostMapping"),
    GET_MAPPING("GetMapping"),
    PUT_MAPPING("PutMapping"),
    DELETE_MAPPING("DeleteMapping"),
    PATCH_MAPPING("PatchMapping");

    AnnotationTypeEnum(String packagePath) {
        this.packagePath = packagePath;
    }

    private String packagePath;

    public String getPackagePath() {
        return packagePath;
    }
}

package com.live.log.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

import static com.live.log.aspect.AnnotationTypeEnum.REQUEST_MAPPING;

@Aspect
@Component
public class LiveLogAspect {


    @Pointcut(value = "execution(public * com.live.controller.*.*(..))") // 切点
    private void controllerPointCut() {
    }


    @Around(value = "controllerPointCut()")
    private Object Around(ProceedingJoinPoint proceedingJoinPoint) {
        Long startTime = System.currentTimeMillis();// 步入时间戳
        Object proceed = null;
        try {
            MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
            Method method = proceedingJoinPoint.getTarget().getClass().getMethod(signature.getName(), signature.getParameterTypes());
            String requestURL = getClassAnnotationPath(proceedingJoinPoint.getTarget().getClass()) + getMethodAnnotationPath(method);
            System.out.println("requestURL:" + requestURL);
            proceed = proceedingJoinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println(System.currentTimeMillis() - startTime + "ms");
        return proceed;
    }

    @AfterThrowing(value = "controllerPointCut()")
    private void AfterThrowing() {
        System.out.println("异常通知");
    }


    private static String getMethodAnnotationPath(Method method) {
        String methodPath = "";
        Annotation[] declaredAnnotations = method.getDeclaredAnnotations();
        for (Annotation annotation : declaredAnnotations) {
            Class<? extends Annotation> annotationType = annotation.annotationType();
            if (REQUEST_MAPPING.getPackagePath().equals(annotationType.getSimpleName())) {
                RequestMapping requestMapping = method.getDeclaredAnnotation(RequestMapping.class);
                String[] value = requestMapping.value();
                if (value.length != 0) {
                    methodPath = value[0];
                }
            }
        }
        return methodPath;
    }

    private static <T> String getClassAnnotationPath (Class<T> targetClass) {
        Annotation[] declaredAnnotations = targetClass.getDeclaredAnnotations();
        String path = "";
        for (Annotation annotation : declaredAnnotations) {
            Class<? extends Annotation> annotationType = annotation.annotationType();
            if (REQUEST_MAPPING.getPackagePath().equals(annotationType.getSimpleName())) {
                RequestMapping requestMapping = targetClass.getDeclaredAnnotation(RequestMapping.class);
                String[] value = requestMapping.value();
                if (value.length != 0) {
                    path = value[0];
                }
            }
        }
        return path;
    }
}

方法二:

package com.live.log.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

import static com.live.log.aspect.AnnotationTypeEnum.REQUEST_MAPPING;

@Aspect
@Component
public class LiveLogAspect {


    @Pointcut(value = "execution(public * com.live.controller.*.*(..))") // 切点
    private void controllerPointCut() {
    }


    @Around(value = "controllerPointCut()")
    private Object Around(ProceedingJoinPoint proceedingJoinPoint) {
        Long startTime = System.currentTimeMillis();// 步入时间戳
        Object proceed = null;
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            String requestURL = request.getRequestURL().toString();
            System.out.println("method:" + request.getMethod());
            System.out.println("requestURL:" + requestURL);
            proceed = proceedingJoinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println(System.currentTimeMillis() - startTime + "ms");
        return proceed;
    }

    @AfterThrowing(value = "controllerPointCut()")
    private void AfterThrowing() {
        System.out.println("异常通知");
    }

笔者在此推荐方法二。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值