技术说明:
springboot:2.1.4.RELEASE
jQuery
Ajax
mysql:8.0.32
业务背景:
当我们在操作网页的时候,我们后台需要记录每个用户,什么时候操作了哪些记录。比如注册了,还是登录了,还是查询了,我们把这些记录全部储存起来,方便管理员查看。
pom.xml
<!--日志记录--><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-api</artifactId><version>2.25.1</version></dependency>
<!--aop切面,方便记录日志--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>
首先定义一个AopContextUtil工具类,里面包含一些常用方法,比如记录用户访问的ip
public class AopContextUtil {/*** 入参数据* @param joinPoint* @param request* @return*/public static String preHandle(JoinPoint joinPoint, HttpServletRequest request) {String reqParam = "";Signature signature = joinPoint.getSignature();MethodSignature methodSignature = (MethodSignature) signature;Method targetMethod = methodSignature.getMethod();Annotation[] annotations = targetMethod.getAnnotations();for (Annotation annotation : annotations) {//此处可以改成自定义的注解if (annotation.annotationType().equals(RequestMapping.class)) {reqParam = JSON.toJSONString(request.getParameterMap());break;}}return reqParam;}/*** 获取IP地址的方法** @param request 传一个request对象下来* @return*/public static String getIpAddress(HttpServletRequest request) {String ip = request.getHeader("x-forwarded-for");if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("Proxy-Client-IP");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("WL-Proxy-Client-IP");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getRemoteAddr();}return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;}
}
定义切面类,就是哪些类哪些方法,需要被记录
@Aspect
@Component
@Slf4j
public class CommonAspect {@Autowiredprivate LogsService logsService;//这是一个日志service层,用来插入到日志数据表里面/*** 定义切点 @Pointcut*/@Pointcut("execution(* com.yuanshengrong.springbootyuanshengrong.controller.*.*(..))")//这里定义的是在这个目录下的controller包下的所有类,所有方法都被记录,就是当用户触发了这个类,这个方法,那就记录下来,用户发起了什么请求。public void log(){}/*** ProceedingJoinPoint仅支持@Around*/@AfterReturning("log()")public void saveOperation(JoinPoint joinPoint){log.info("---------------接口日志记录---------------");// 创建一个日志对象(准备记录日志)LogsDo logsDo = new LogsDo();HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();//IP地址String ipAddr = AopContextUtil.getIpAddress(request);//AopContextUtil前面有定义,获取ip的logsDo.setClientip(ipAddr);//urlString url = request.getRequestURL().toString();//用户发起的请求链接logsDo.setOperurl(url);//请求参数/* String reqParam =AopContextUtil.preHandle(joinPoint,request);logsDo.setReqparam(reqParam);*/// 1.方法执行前的处理,相当于前置通知// 获取方法签名MethodSignature signature = (MethodSignature) joinPoint.getSignature();//获取切入点所在的方法Method method = signature.getMethod();// 获取方法上面的注解LogAnno logAnno = method.getAnnotation(LogAnno.class);if (logAnno !=null){// 获取操作描述的属性值String operateType = logAnno.operateType();// 保存操作说明logsDo.setOpertype(operateType);}//TODO 设置操作人,从session中获取。String username = (String)request.getSession().getAttribute("username");//从session中获取用户名,记录是哪个用户操作的//保存用户名到数据库logsDo.setUsername(username);// 设置操作日期logsDo.setOpertime(new Date());logsService.insertSelective(logsDo);}
}
@Target(ElementType.METHOD) // 方法注解
@Retention(RetentionPolicy.RUNTIME) // 运行时可见
public @interface LogAnno {String operateType();// 记录日志的操作类型
}
上面这个代码,是用来记录日志的,我们只需要在方法上加上@LogAnno(operateType = "导出面试信息Excel记录"),用来记录操作的日志类型即可