簡單的接口的請求日誌攔截工具類

捕捉每個接口的請求參數,請求時間,請求方式,返回參數,返回時間,執行時間,異常信息

技術:AOP切面

程序

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

數據庫表結構

見效果圖

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章