LogAnnotationAOP.java 4.5 KB
package com.tianbo.warehouse.annotation;

import com.alibaba.fastjson.JSON;
import com.tianbo.warehouse.model.LOGWithBLOBs;
import com.tianbo.warehouse.service.LogService;
import com.tianbo.warehouse.util.IO.StreamUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;


@Aspect
@Component
public class LogAnnotationAOP {

    @Autowired
    private LogService logService;

    private LOGWithBLOBs log;

    @Pointcut("@annotation(com.tianbo.warehouse.annotation.LogAnnotation)")
    public void annotationPointCut(){

    }

    @Before("annotationPointCut()")
    public void before(JoinPoint point){
        //获取当前登录用户信息
        try{
            UserDetails userDetails =(UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            String requestRemoteAddr = request.getRemoteAddr();

            log.setIp(requestRemoteAddr);
            log.setUsername(userDetails.getUsername());
        }catch (Exception e){
            e.printStackTrace();
        }

        try{
            String targetName = point.getTarget().getClass().getName();
            Class targetClass = Class.forName(targetName);

            MethodSignature signature = (MethodSignature) point.getSignature();
            Method method= signature.getMethod();
            LogAnnotation annotation = method.getAnnotation(LogAnnotation.class);
            System.out.print("打印:"+annotation.moduleName()+" 开始前");
            String methodName = point.getSignature().getName();
//            Method[] methods = targetClass.getMethods();


            if(annotation != null){
                log.setModelnamecn(annotation.moduleName());
                log.setOperatenamecn(annotation.operate());
            }
            log.setClassname(targetName);
            log.setMethodname(methodName);

            // 获得参数列表
            Object[] params = point.getArgs();
            if(params.length>0){
                //序列化时过滤掉request和response,参考资料为:https://blog.csdn.net/hbn1326317071/article/details/83818059
                List<Object> logArgs = StreamUtil.streamOf(params)
                        .filter(arg -> (!(arg instanceof HttpServletRequest) && !(arg instanceof HttpServletResponse) && !(arg instanceof BindingResult)))
                        .collect(Collectors.toList());

                //将参数列表转成JSON存储
                log.setParameters(JSON.toJSONString(logArgs));
            }

        }catch (ClassNotFoundException e){
            e.printStackTrace();
            log.setResult(JSON.toJSONString(e));
            logService.insertSelective(log);
        }




    }

    @Around("annotationPointCut()")
    public Object advice(ProceedingJoinPoint joinPoint){
        System.out.println("通知之开始");
        log = new LOGWithBLOBs();

        Object retmsg=null;
        try {
            retmsg=joinPoint.proceed();
            System.err.println("++++++++"+retmsg);
        } catch (Throwable e) {
            e.printStackTrace();
        }
        System.out.println("通知之结束");
        return retmsg;
    }

    @After("annotationPointCut()")
    public void after(){
        System.out.println("after方法执行后");
    }

    /**
     * 方法正常完成后执行方法
     * @param retmsg 这里的retmsg= advice中的Object retmsg
     */
    @AfterReturning(returning = "retmsg",pointcut="annotationPointCut()")
    public void afterReturn(Object retmsg) throws Throwable{

        // 处理完请求,返回内容
        log.setResult(JSON.toJSONString(retmsg));

        logService.insertSelective(log);
    }
}