用Aspect 做方法的後置增強@AfterReturning和異常增強@AfterThrowing

業務場景

	所有進入controller的請求做請求統計
	1、用了統一異常處理方法@ControllerAdvice
	2、統計請求的方法連接 及入參
	3、統計方法的返回狀態(200?)及參數

正常增強 **filter(JoinPoint joinPoint, Object result) **

異常增強 **error(JoinPoint jp,Throwable ex) **

package com.mf.gateway.filter;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.clouder.platform.service.AdminService;
import com.clouder.platform.service.SysOperLogService;
import com.google.common.collect.Maps;
import org.apache.dubbo.config.annotation.Reference;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
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.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;


@Aspect
@Component
public class LogContainerResponseFilter{

    private static final Logger logger = LoggerFactory.getLogger(LogContainerResponseFilter.class);

    @Reference
    private SysOperLogService sysOperLogService;

    @Reference
    private AdminService adminService;

    private boolean decode = false;

    SerializerFeature[] features = new SerializerFeature[] {
            SerializerFeature.QuoteFieldNames, SerializerFeature.SortField,
            SerializerFeature.DisableCircularReferenceDetect };

    private static final List<String> HEAD_NOT_INCLUDE = Arrays.asList("Accept", "Accept-Encoding", "Accept-Charset",
            "Accept-Language", "Connection", "Content-Encoding", "Content-Type", "Vary", "Cache-Control", "Cookie",
            "Host", "accept", "accept-encoding", "accept-charset", "accept-language", "connection", "content-encoding",
            "content-type", "vary", "cache-control", "cookie", "host","content-length");

    private static final AtomicLong atomicLong = new AtomicLong(0);

    private static List<String> specialUrl = Arrays.asList("user/login");


    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    /**
     * RestResp  是controler 設置的一個統一返回對象,此處不給予代碼
     *Log  是一個自定義註解,對需要做統計的方法添加此註解,註解上標註方法的屬性等信息  此處不給予代碼
     */


    @Pointcut("@annotation(com.cn.test.util.Log)") //切點是 自定義註解Log 的地址
    public void logPointCut() {

    }


    @AfterReturning(value="logPointCut()",returning="result")
    public void filter(JoinPoint joinPoint, Object result) throws IOException {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        if (!"POST".equalsIgnoreCase(request.getMethod())){
            return;
        }
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Log log = method.getAnnotation(Log.class);
        if (log ==null ){
            return;
        }

        Cookie[] cookies = request.getCookies();
        
        //獲取請求入參
        Map<String, String> map = getFormParameters(request);
        if (null != map && map.containsKey("password")){
            map.remove("password");
        }

        /**
         * 此處邏輯 就是方法正常的處理邏輯,不予贅述
         * 此處處理後方執行 @ControllerAdvice邏輯
         */
      
    }


    @AfterThrowing(pointcut = "logPointCut()",throwing = "ex")
    public void error(JoinPoint jp,Throwable ex) throws UnsupportedEncodingException {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        if (!"POST".equalsIgnoreCase(request.getMethod())){
            return;
        }
        MethodSignature signature = (MethodSignature) jp.getSignature();
        Method method = signature.getMethod();
        Log log = method.getAnnotation(Log.class);
        if (log ==null ){
            return;
        }

        /**
         * 此處邏輯 就是方法異常的處理邏輯,不予贅述
         */

    }



    private Map<String, String> getFormParameters(HttpServletRequest request) {
        Map<String ,String > paramsMap = Maps.newHashMap();
        Enumeration enu=request.getParameterNames();
        while(enu.hasMoreElements()){
            String paraName=(String)enu.nextElement();
            paramsMap.put(paraName ,request.getParameter(paraName));
        }
        return paramsMap;
    }

    private static boolean isLogin(String serverUrl){
        if(serverUrl.contains("user/login")){
            return true;
        }
        return false;
    }



    private static String getIpAddr(HttpServletRequest rc){
        if (rc == null)
        {
            return "unknown";
        }
        String ip = rc.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = rc.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = rc.getHeader("X-Forwarded-For");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = rc.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = rc.getHeader("X-Real-IP");
        }
        return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
    }
}

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