欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring boot自定义切面拦截所有的请求 或者方法原理一样

程序员文章站 2024-02-14 09:41:52
...

原代码

下面的例子是小编在自己的环境中测试过得。

代码

**@Pointcut("!execution(public * com..controller.SysLoginController.*(..))* and " +
           "!execution(public * com..controller.SysLoginController.*(..))* and " +
            "execution(public * com..controller.*.*(..))*")**

1.切面中的多个条件可以使用and和&&符号来连接。
2.切面中需要排除的方法可以使用!execution来排除掉。


package com.******.***.admin.util;
import com.alibaba.fastjson.JSON;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
/**
 * @author Andya
 * @create 2020-04-12 10:39
 */
@Aspect
@Component
public class RequesAspect {

    private Logger LOG = LoggerFactory.getLogger(RequesAspect.class);

    ThreadLocal<Long> startTime = new ThreadLocal<>();

    /**
     * 定义切入点,以controller下所有包的请求为切入点
     */
//    @Pointcut("!execution(public * com..controller.SysLoginController.*(..))* and " +
//            "!execution(public * com..controller.SysLoginController.*(..))* and " +
//            "execution(public * com..controller.*.*(..))*")
    @Pointcut( "execution(public * com.chase.upay.admin.controller.*.*(..))*")
    public void webLog(){

    }

    /**
     *前置通知:在切入点之前执行的通知
     * @param joinPoint
     * @throws Throwable
     */
    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {

        startTime.set(System.currentTimeMillis());
         //下面是拦截所有请求里面的token,要是发现token不读,直接爆出异常
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();
        String token = request.getHeader("token");
        String url = request.getRequestURL().toString();
        //JwtTokenUtils是自定义的token验证类,您可以根据您自己项目的实际的token验证方法来验证
        LOG.info("token是否在有效的时间范围内:" + JwtTokenUtils.isTokenExpired(token));
        if (JwtTokenUtils.isTokenExpired(token) && !url.contains("captcha.jpg")) {
            throw new Exception("TOKEN失效");
        }

        //打印请求相关参数
        LOG.info("========================================== Start ==========================================");

        LOG.info("URL:" + request.getRequestURL().toString());

        LOG.info("HTTP_METHOD:" + request.getMethod());


        //header第一种格式展示
        Enumeration<String> enumeration = request.getHeaderNames();
        Map<String, String> headerMap = new HashMap<>();
        while (enumeration.hasMoreElements()) {
            String headerName = enumeration.nextElement();
            headerMap.put(headerName, request.getHeader(headerName));
        }
        String headerJsonStr = JSON.toJSONString(headerMap);
        if (headerJsonStr.length() > 0) {
            LOG.info("HTTP_HEADERS INFO IS: {}", headerJsonStr);
        }

        //header第二种格式展示
        LOG.info("HTTP_HEADERS: ");
        Enumeration<?> enumeration1 = request.getHeaderNames();
        while (enumeration1.hasMoreElements()) {
            String key = (String) enumeration1.nextElement();
            String value = request.getHeader(key);
            LOG.info("     {}: {}", key, value);
        }

        LOG.info("IP:" + request.getRemoteAddr());

        LOG.info("CLASS_METHOD:" + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        try {
            LOG.info("REQUEST BODY : [{}]", JSON.toJSONString(joinPoint.getArgs()[0]));
//            LOG.info("ARGS:{}", Arrays.toString(joinPoint.getArgs()));
        } catch (Exception e) {
            LOG.error("REQUEST BODY PARSE ERROR!");
        }

        HttpSession session = (HttpSession) servletRequestAttributes.resolveReference(RequestAttributes.REFERENCE_SESSION);
        LOG.info("SESSION ID:" + session.getId());


    }


    /**
     * 后置通知
     * @param ret
     * @throws Throwable
     */
    @AfterReturning(returning = "ret", pointcut = "webLog()")
    public void doAfterReturning(Object ret) throws Throwable {
        // 处理完请求,返回内容
        LOG.info("RESPONSE : " + ret);
        LOG.info("SPEND TIME : " + (System.currentTimeMillis() - startTime.get()));

    }


    /**
     * 后置最终通知
     * @throws Throwable
     */
    @After("webLog()")
    public void doAfter() throws Throwable {
        LOG.info("=========================================== End ===========================================");
        // 每个请求之间空一行
        LOG.info("");
    }


    /**
     * 环绕通知
     * 环绕通知第一个参数必须是org.aspectj.lang.ProceedingJoinPoint类型
     * @param proceedingJoinPoint
     * @return
     * @throws Throwable
     */
    @Around("webLog()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object result = proceedingJoinPoint.proceed();
        String resultStr = JSON.toJSONString(result);
        // 打印出参
        LOG.info("RESPONSE ARGS  : {}", resultStr);
        // 执行耗时
        LOG.info("TIME-CONSUMING : {} ms", System.currentTimeMillis() - startTime);
        return result;
    }

}