spring aop实现接口请求记录

一、背景

接到一个需求,记录每个用户,在系统进行的修改、添加和删除的操作记录。

二、具体实现

日志记录,与主业务没有直接联系,不进行业务处理,故符合spring aop面向切面的编程思想。所以采用aop,来完成这一任务。

废话少说,直接上代码,代码参考了其他博主的文章,并结合实际情况进行修改。

@Aspect
@Component
@Slf4j
@Order(value = 3)//项目启动自动执行顺序
public class ThirdApiRequestLogAspect{
	ObjectMapper objectMapper = new ObjectMapper();
	
	@Autowired
	private OperationLogMapper operationLogMapper;
	
	@Autowired 
	private UserPersistenceService userPersistenceService;
	
	//过滤不保存的方法
	final String [] filtration = {"DeviceApiController.searchDeviceList"};


	
	public ThirdApiRequestLogAspect() {
		log.info("初始化接口日志切面类...");
	}
	
    //切入点,该切入点下的方法都会执行该切面方法
	@Pointcut("execution(public * com.it.foundwater.controller.*.*(..))")
	public void controllerInteceptor() {
		
	}
	
    //环绕通知/环绕增强
	@Around("controllerInteceptor()")
	public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
		Method method = signature.getMethod();
		Date start = new Date();
		Object o = null;
		try {
			//操作日志实体
			OperationLog sysLog = new OperationLog();
			ApiOperation syslog1 = method.getAnnotation(ApiOperation.class);
			if(syslog1!=null) {
				//注解上的描述
				sysLog.setMethod(syslog1.value());
			}
			//请求的方法名
			String clazzName = joinPoint.getTarget().getClass().getName();
			Class<?> clazz = Class.forName(clazzName);
			String clazzSimpleName = clazz.getSimpleName();
			String methodName = signature.getName();
			sysLog.setOperationDesc(clazzSimpleName+'.'+methodName);
			//请求的参数
            String[] parameterNames = ((MethodSignature) joinPoint.getSignature()).getParameterNames();
            StringBuilder sb = null;
            if (Objects.nonNull(parameterNames)) {
                sb = new StringBuilder();
                for (int i = 0; i < parameterNames.length; i++) {
                    Object param = joinPoint.getArgs()[i] != null ? joinPoint.getArgs()[i] : "";
                    if (StringUtils.isNotEmpty(param.toString()) && !"request".equals(parameterNames[i]) && !"response".equals(parameterNames[i])
                            && !"modelMap".equals(parameterNames[i])) {
                        if (param instanceof Integer) {
                            sb.append(parameterNames[i] + ":" + param + "; ");
                        } else if (param instanceof String) {
                            sb.append(parameterNames[i] + ":" + param + "; ");
                        } else if (param instanceof Double) {
                            sb.append(parameterNames[i] + ":" + param + "; ");
                        } else if (param instanceof Float) {
                            sb.append(parameterNames[i] + ":" + param + "; ");
                        } else if (param instanceof Long) {
                            sb.append(parameterNames[i] + ":" + param + "; ");
                        } else if (param instanceof Boolean) {
                            sb.append(parameterNames[i] + ":" + param + "; ");
                        } else if (param instanceof Date) {
                            sb.append(parameterNames[i] + ":" + param + "; ");
                        } else if (param instanceof Timestamp) {
                            sb.append(parameterNames[i] + ":" + param + "; ");
                        } else {
                            sb.append(parameterNames[i] + ":" + getString(param) + "; ");
                        }
                    }
                }
            }
            
            sb = sb == null ? new StringBuilder() : sb;
            sysLog.setParams(sb.toString());
            //设置IP地址
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            User user = null;
            if(StringUtils.isNotEmpty(methodName)&&"login".equals(methodName)) {
            	//为登录接口没有session
            	user = this.getDecodeUserName(request,1,sb.toString());
            }else {
            	user = this.getDecodeUserName(request,0,"");
            }
            sysLog.setIp(IpAddressUtil.getIpAddr(request));
            sysLog.setUserName(user==null?null:user.getName());
            sysLog.setCreateTime(LocalDateTime.now());
            sysLog.setLoginName(user==null?null:user.getLoginName());
            log.debug("interface request startTime " + start.getTime());
            o = joinPoint.proceed();
            String response = objectMapper.writeValueAsString(o);
            //get查询请求不记录
            if("GET".equals(request.getMethod())) {
            	log.info("查询请求不记录:"+request.getMethod());
            	return o;
            }
            if(Arrays.asList(filtration).contains(sysLog.getOperationDesc())) {
            	log.info("该请求不记录:"+sysLog.getOperationDesc());
            	return o;
            }
            sysLog.setReturnResult(response);
            sysLog.setTimeMin(System.currentTimeMillis() - start.getTime());
            log.debug(getString(sysLog));
            //保存系统日志
             operationLogMapper.insert(sysLog);
            return o;
		} catch (Exception e) {
			// TODO: handle exception
			log.error("保存系统日志失败"+e);
			o = joinPoint.proceed();
		}
		return o;
	}
	
	//各个项目获取用户信息不同,根据自己项目进行修改
	public User getDecodeUserName(HttpServletRequest request,Integer type,String params) {
		User user  = null;
		Long userId = null; 
		String loginName=null;
        try {
        	if(null!=type&&0==type) {
        		userId = (Long) request.getSession().getAttribute("CURRENT_USER_ID");
        	}else if(null!=type&&1==type) {
        		String p = params;
        		String p1 = p.substring(p.indexOf("[")+1,p.indexOf("]"));
        		System.out.println(p1);
        	    String [] p2 = p1.split("\\|");
        	    for(String p3:p2) {
        	    	if(p3.indexOf("loginName")>=0) {
        	    		loginName=p3.substring(p3.indexOf("=")+1);
        	    	}
        	    }
        	}
        	//过滤没有token时的false情况
	        if(null!=userId) {
	        	user = userPersistenceService.getById(userId);
	        	return user;
	        }
	        //登录接口
	        if(StringUtils.isNotEmpty(loginName)) {
	        	user = userPersistenceService.findUserByLoginName(loginName);
	        }
        } catch (Exception e) {
            log.error("获取用户名失败"+e.getMessage(), e);
        } 
        return user;
    }
	
	 public static String getString(Object o) {
	        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	        StringBuffer sb = new StringBuffer();
	        sb.append("entity[");
	        Field[] farr = o.getClass().getDeclaredFields();
	        for (Field field : farr) {
	            try {
	                field.setAccessible(true);
	                if (field.get(o)!=null) {
	                    sb.append(field.getName());
	                    sb.append("=");
	                    if (field.get(o) instanceof Date) {
	                        // 日期的处理
	                        sb.append(sdf.format(field.get(o)));
	                    } else {
	                        sb.append(field.get(o));
	                    }
	                    sb.append("|");
	                }

	            } catch (Exception e) {
	                e.printStackTrace();
	            }
	        }
	        sb.append("]");
	        return sb.toString();
	    }


}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值