aop日志切面(日期未处理)

本文档详细描述了一个Spring Boot应用中的AOP切面,通过@RequestLog注解监控API调用,记录执行时长、用户信息、操作类型,并在数据更新时对比前后值。特别关注了如何获取请求IP和处理不同情况下的IP获取方式。
摘要由CSDN通过智能技术生成

@Component
@Aspect
@Slf4j
public class SysLogAspect {

    @Autowired
    private SysLogDao sysLogDao;
    @Autowired
    private LogRecordOldInfo oldInfo;

    @Pointcut("@annotation(com.RequestLog)")
    public void logPointCut() {
    }

    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint //连接点
                                 point) throws Throwable {
        Exception exception = null;
        long totalTime = 0L;
        Object result = null;
        String isSuccessful = "1";
        String changeParams = "";
        //获取要拦截的方法基础信息
        MethodSignature ms =
                (MethodSignature) point.getSignature();
        Class<?> targetClass =
                point.getTarget().getClass();
        String className = targetClass.getName();
        //获取接口声明的方法
        String methodName = ms.getMethod().getName();
        Class<?>[] parameterTypes = ms.getMethod().getParameterTypes();
        Class<?> parameterType = parameterTypes[0];
        //获取目标对象方法
        Method targetMethod = targetClass.getDeclaredMethod(
                methodName, parameterTypes);
        RequestLog requestLog =
                targetMethod.getDeclaredAnnotation(RequestLog.class);
        //如果是修改数据,则查询修改之前数据
        if ("update".equals(requestLog.opera())) {
            //获取方法参数
            Object[] fields = point.getArgs();
            //将新传入的参数转换为字符串
            String params = new ObjectMapper().writeValueAsString(fields);
            //将json类型的字符串转换为map
            params = params.substring(2, params.length() - 2);
            String[] newArray = params.split(",\"");
            HashMap<String, Object> newMap = new HashMap<>();
            for (String array1 : newArray) {
                array1 = array1.replaceAll("\"", "");
                if (array1.contains(":") && !array1.contains("-")) {
                    String[] array2 = array1.split(":");
                    newMap.put(array2[0], array2[1]);
                }
            }
            //获取修改的数据id,方便查询原数据比较
            String id = newMap.get("id") == null ? "" : newMap.get("id").toString();
            //获取当前要修改的表名
            String tableName = parameterType.getAnnotation(TableName.class).value();
            //根据id查询修改之前的数据
            //newmap是驼峰形式
            LinkedHashMap<String, Object> oldMap = oldInfo.selectById(id, tableName);
            for (Map.Entry<String, Object> entry : newMap.entrySet()) {
                String mapKey = entry.getKey() == null ? "" : entry.getKey();
                String newValue = entry.getValue() == null ? "" : entry.getValue().toString();
                String oldValue = oldMap.get(StringUtils.camelToUnderline(mapKey)) == null ? "" : oldMap.get(StringUtils.camelToUnderline(mapKey)).toString();
                if (!oldValue.isEmpty() && !newValue.isEmpty() && !oldValue.equalsIgnoreCase(newValue)) {
                    changeParams += (mapKey + "字段update;oldData:" + oldValue + ";newData:" + newValue + ";");
                }
            }
        }
        //判定目标方法上是否有RequestLog注解
        boolean flag = targetMethod.isAnnotationPresent(RequestLog.class);
        //登陆的用户
        UserAuth authUser = SecurityUtils.getAuthUser();
        String username = authUser.getRealName();
        //封装日志信息
        SysLog logInfo = new SysLog();
        logInfo.setUsername(username);
        //假如目标方法对象上有注解,获取注解定义的操作值
        if (flag) {
            logInfo.setOperation(requestLog.value());
        }
        try {
            //执行拦截的方法,获取执行耗费时间
            long startTime = System.currentTimeMillis();
            result = point.proceed();
            long endTime = System.currentTimeMillis();
            totalTime = endTime - startTime;
            log.info("方法执行的总时长为:" + totalTime);
        } catch (Exception e) {
            exception = e;
            log.error("日志记录error:", e);
        } finally {
            if (exception == null) {
                isSuccessful = "0";
            }
            logInfo.setParams(changeParams);
            logInfo.setMethod(className + "." + methodName);
            logInfo.setIsSuccessful(isSuccessful);
            logInfo.setIp(IPUtils.getIpAddr());
            logInfo.setTime(totalTime);
            logInfo.setCreatedTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            //保存日志信息
            sysLogDao.insert(logInfo);
            return result;
        }
    }


}

 ip获取

@Slf4j
public class IPUtils {

    public static String getIpAddr() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String ip = null;
        try {
            ip = request.getHeader("x-forwarded-for");
            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
        } catch (Exception e) {
            log.error("IPUtils ERROR ", e);
        }
        return ip;
    }
}
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestLog {
    public String opera() default "";
    //aop获取value的值
    public String value() default "";


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值