日志拦截每个接口的请求信息日志

背景:需要拦截每个接口的请求参数,请求时间,请求方式,返回参数,返回时间,执行时间,异常信息

解决方式,利用切面拦截

切面类:

package com.movitech.contract.config;

import com.alibaba.fastjson.JSON;
import com.google.gson.Gson;
import com.movitech.commons.entity.LogRecordBean;
import com.movitech.contract.dao.LogRecordDao;
import com.movitech.contract.dao.OauthDao;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
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 java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Aspect //  声明切面
@Component //声明组件
@ComponentScan //组件自动扫描
@EnableAspectJAutoProxy //spring自动切换JDK动态代理和CGLIB
public class LogAspect {
    @Autowired
    private LogRecordDao logRecordDao;
    @Autowired
    private OauthDao oauthDao;
    @Pointcut("execution(public * com.movitech.contract.controller.*.*(..))")
    public void methodPointCut() {

    }

    @Around("methodPointCut()")
    public Object doBeforeAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();

        String url = request.getRequestURL().toString();
        String method = request.getMethod();
        /*-------------------------------------通过uri获取aApiId---------------------------*/
        String uri = request.getRequestURI();
        int num = uri.length() - uri.replace("/","").length();
        if(num >= 4){
            //截取/a/b/c三层后面的字符
            uri = getStr(uri,3);
        }
        Integer aApiId = oauthDao.getAApiId(uri);
        /*---------------------------------------------end---------------------------------*/
        String queryString = request.getQueryString();
        Object[] args = joinPoint.getArgs();
        String params = "";

        LogRecordBean logRecordBean = new LogRecordBean();
        try {
            //获取请求参数集合并进行遍历拼接
            if (args.length > 0) {
                if ("POST".equals(method)) {
                    if (args.length > 1) {
                        params = args.toString();
                    } else {
                        Object object = args[0];
                        Map map = getKeyAndValue(object);
                        params = JSON.toJSONString(map);
                    }

                } else if ("GET".equals(method)) {
                    params = queryString;
                    if (params == null) {
                        params = "";
                        for (int i = 0; i < args.length; i++) {
                            params = params + "+" + args[i];
                        }
                        params = params.substring(1);
                    }
                }
            }
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Gson gson = new Gson();
            long beginTime = System.currentTimeMillis();

            logRecordBean.setBeginTime(simpleDateFormat.format(new Date(System.currentTimeMillis())));
            logRecordBean.setAApiId(aApiId);
            logRecordBean.setApiName(uri);
            logRecordBean.setMethod(method);
            logRecordBean.setParams(params);
            // result的值就是被拦截方法的返回值
            Object result = joinPoint.proceed();

            logRecordBean.setResult(gson.toJson(result));
            logRecordBean.setEndTime(simpleDateFormat.format(new Date(System.currentTimeMillis())));

            long endTime = System.currentTimeMillis();
            long betweenTime = endTime - beginTime;
            logRecordBean.setBetweenTime(String.valueOf(betweenTime));
            logRecordDao.addLogRecord(logRecordBean);
            return result;
        } catch (Exception e) {
            logRecordBean.setExceptionMessage(e.getMessage());
            logRecordDao.addLogRecord(logRecordBean);
            throw new RuntimeException(e.getMessage());
        }
    }

    public static Map<String, Object> getKeyAndValue(Object obj) {
        Map<String, Object> map = new HashMap<>();
        // 得到类对象
        Class userCla = (Class) obj.getClass();
        /* 得到类中的所有属性集合 */
        Field[] fs = userCla.getDeclaredFields();
        for (int i = 0; i < fs.length; i++) {
            Field f = fs[i];
            f.setAccessible(true); // 设置些属性是可以访问的
            Object val = new Object();
            try {
                val = f.get(obj);
                // 得到此属性的值
                map.put(f.getName(), val);// 设置键值
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return map;
    }
    public static String getStr(String str, int n) {
        int i = 0;
        int s = 0;
        while (i++ < n) {
            s = str.indexOf("/", s + 1);
            if (s == -1) {
                return str;
            }
        }
        return str.substring(0, s);
    }
}

还需添加一些map方面的类,可根据自己的表结构来设置,比较简单

数据库表:

猜你喜欢

转载自blog.csdn.net/qq_34707991/article/details/81739940
今日推荐