-
导入打印日志,aop,hutool,的依赖,Hutool是一个Java工具包,里面封装了大量的常用工具类,到时候咱们就通过这个工具包中有一个工具类可以用来获取客户端IP地址。
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.6.3</version> </dependency>
-
自定义操作类型枚举类 因为基本是增删改查四个方法
/** * 操作类型枚举类 * @author lichuan */ public enum OperationTypeEnum { /** * 新增操作 */ INSERT("新增"), /** * 修改操作 */ UPDATE("修改"), /** * 删除操作 */ DELETE("删除"), /** * 查询操作 */ QUERY("查询"), /** * 其它 */ OTHER("其它"); private String operationType; OperationTypeEnum(String operationType) { this.operationType = operationType; } public String getOperationType() { return operationType; } }
-
自定义用来记录用户操作日志的注解
@Target(ElementType.METHOD) //注解放置的目标位置,METHOD是可注解在方法级别上 @Retention(RetentionPolicy.RUNTIME) //注解在哪个阶段执行 @Documented public @interface OperationLog { /** * 操作模块 * @return */ String operationModule() default ""; /** * 操作类型 * @return */ OperationTypeEnum operationType() default OperationTypeEnum.OTHER; /** * 操作说明 * @return */ String description() default ""; }
-
写一个方法加上我们自定义的注解
- 定义用来记录用户操作日志的切面类
import cn.hutool.extra.servlet.ServletUtil; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import javax.servlet.http.HttpServletRequest; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; /** * @author lichuan */ @Aspect @Component @Slf4j public class OperationLogAspect { /** * 设置操作日志切入点,在注解的位置切入代码 */ @Pointcut("execution(public * com.tm.controller..*Controller.*(..))") public void operationLogPointCut() { } /** * 定义环绕通知 * 1. 环绕通知需要携带ProceedingJoinPoint类型的参数 * 2. 环绕通知类似于动态代理的全过程ProceedingJoinPoint类型的参数可以决定是否执行目标方法 * 3. 且环绕通知必须有返回值,返回值即目标方法的返回值 */ @Around("operationLogPointCut()") public Object around(ProceedingJoinPoint joinPoint) { Object result = null; //获取系统当前时间毫秒值 long beginTime = System.currentTimeMillis(); log.info("环绕通知开始"); try { //执行目标方法 result = joinPoint.proceed(); } catch (Throwable e) { e.printStackTrace(); } //获取系统当前时间毫秒值 long endTime = System.currentTimeMillis(); // 获取RequestAttributes RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); // 从获取RequestAttributes中获取HttpServletRequest的信息 HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST); //获取ip String clientIP = ServletUtil.getClientIP(request); log.info(clientIP); //获取目标方法执行时间 long usageTime = endTime - beginTime; // operationLogEntity.setUsageTime(usageTime); try { // 从切面织入点处通过反射机制获取织入点处的方法 MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // 获取切入点所在的方法 Method method = signature.getMethod(); //System.out.println(method); // 获取操作 OperationLog operationLog = method.getAnnotation(OperationLog.class); if (operationLog != null) { log.info(operationLog.operationModule()); log.info(operationLog.description()); log.info(operationLog.operationType().getOperationType()); } // 获取请求的类名 String className = joinPoint.getTarget().getClass().getName(); // 获取请求的方法名 String methodName = method.getName(); methodName = className + "." + methodName; log.info(methodName); // 请求方法 // operationLogEntity.setMethodName(methodName); // 请求的参数 Map<String, String> parameterMap = ServletUtil.getParamMap(request); // 将参数所在的数组转换成json String requestParams = new ObjectMapper().writeValueAsString(parameterMap); // 请求参数 System.out.println(parameterMap); log.info(requestParams); // 返回结果 log.info(new ObjectMapper().writeValueAsString(result)); // 请求URL log.info(request.getRequestURL().toString()); // 请求URI log.info(request.getRequestURI()); // 创建时间 // operationLogEntity.setCreateTime(new Date()); // System.out.println(operationLogEntity); log.info("环绕通知结束"); } catch (Exception e) { } return result; } /** * 转换request 请求参数 * @param parameterMap request获取的参数数组 */ public Map<String, String> convertParameterMap(Map<String, String[]> parameterMap) { Map<String, String> convertParameterMap = new HashMap<>(); for (String key : parameterMap.keySet()) { convertParameterMap.put(key, parameterMap.get(key)[0]); } return convertParameterMap; } }
6.测试
文章来源:https://www.toymoban.com/news/detail-457722.html
调用test方法,可以看到控制台已经打印出了日志信息,创建表的对象存入即可文章来源地址https://www.toymoban.com/news/detail-457722.html
到了这里,关于Java使用Aop实现用户操作日志记录(新手入门)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!