- 导入打印日志,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) //注解在哪个阶段执行@Documentedpublic @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.测试
调用test方法,可以看到控制台已经打印出了日志信息,创建表的对象存入即可
本文转载自: https://blog.csdn.net/m0_56759222/article/details/129453592
版权归原作者 空指针异常z 所有, 如有侵权,请联系我们删除。
版权归原作者 空指针异常z 所有, 如有侵权,请联系我们删除。