package design.model.business.domain.entity;
import java.io.Serializable;
/**
* 用户操作日志实体
*
* @author XXX email: 1464025388@qq.com
* creation time: 2023/01/02 13:01:00
*/
public class UserOperationLogEntity implements Serializable {
private static final long serialVersionUID = 3864884180759675910L;
/**
* id
*/
private String id;
/**
* 用户代码
*/
private String userCode;
/**
* 用户名
*/
private String userName;
/**
* ip addr
*/
private String ipAddr;
/**
* url
*/
private String url;
/**
* 行为类型
*/
private String behaviorType;
/**
* 描述
*/
private String description;
/**
* 模型
*/
private String model;
/**
* 操作时间
*/
private String operationTime;
/**
* 结果
*/
private String result;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUserCode() {
return userCode;
}
public void setUserCode(String userCode) {
this.userCode = userCode;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getIpAddr() {
return ipAddr;
}
public void setIpAddr(String ipAddr) {
this.ipAddr = ipAddr;
}
public String getBehaviorType() {
return behaviorType;
}
public void setBehaviorType(String behaviorType) {
this.behaviorType = behaviorType;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getOperationTime() {
return operationTime;
}
public void setOperationTime(String operationTime) {
this.operationTime = operationTime;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
@Override
public String toString() {
return "UserOperationLogEntity{" +
"id='" + id + '\'' +
", userCode='" + userCode + '\'' +
", userName='" + userName + '\'' +
", ipAddr='" + ipAddr + '\'' +
", url='" + url + '\'' +
", behaviorType='" + behaviorType + '\'' +
", description='" + description + '\'' +
", model='" + model + '\'' +
", operationTime='" + operationTime + '\'' +
", result='" + result + '\'' +
'}';
}
}
控制器
package design.model.business.controller;
import design.model.business.interfaces.OperationModuleContains;
import design.model.business.utils.annotation.OperationLogAnnotation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/user/operation/log")
public class UserOperationLogController {
@OperationLogAnnotation(operModul = OperationModuleContains.MODULE_BUSINESS,
operType = OperationModuleContains.OperationTypeContains.LOGIN)
@GetMapping("/login")
public String login() {
return "登录成功";
}
}
注解接口
package design.model.business.utils.annotation;
import java.lang.annotation.*;
/**
* 操作日志注释
*
* @author XXX email: 1464025388@qq.com
* creation time: 2022/12/29 15:12:25
*/
@Target(ElementType.METHOD) 注解放置的目标位置即方法级别
/**
* @Target(ElementType.TYPE)——接口、类、枚举、注解
* @Target(ElementType.FIELD)——字段、枚举的常量
* @Target(ElementType.METHOD)——方法
* @Target(ElementType.PARAMETER)——方法参数
* @Target(ElementType.CONSTRUCTOR) ——构造函数
* @Target(ElementType.LOCAL_VARIABLE)——局部变量
* @Target(ElementType.ANNOTATION_TYPE)——注解
* @Target(ElementType.PACKAGE)——包,用于记录java文件的package信息
*/
@Retention(RetentionPolicy.RUNTIME)//注解在哪个阶段执行
/**
* RetentionPolicy.SOURCE
* 表示注解只保留在源文件,当java文件编译成class文件,就会消失 源文件 只是做一些检查性的操作,,比如 @Override 和 @SuppressWarnings
* RetentionPolicy.CLASS
* 注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期 class文件(默认) 要在编译时进行一些预处理操作,比如生成一些辅助代码(如 ButterKnife)
* RetentionPolicy.RUNTIME
* 注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在 运行时也存在 需要在运行时去动态获取注解信息
*/
@Documented
public @interface OperationLogAnnotation {
String modul() default ""; // 操作模块
String type() default ""; //操作类型
String desc() default ""; //操作说明
}
AOP逻辑实现,插入日志
package design.model.business.utils.annotation;
import com.alibaba.fastjson.JSON;
import design.model.business.mapper.aop.OperationLogMapper;
import design.model.business.domain.entity.UserOperationLogEntity;
import design.model.business.utils.id.UuidUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
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.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
/**
* 操作日志方面
*
* @author XXX email: 1464025388@qq.com
* creation time: 2022/12/30 17:12:74
*/
@Aspect
@Component
public class OperationLogAspect {
@Autowired
private OperationLogMapper operationLogMapper;
private static final Logger logger = LoggerFactory.getLogger(OperationLogAspect.class);
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
/**
* 设置操作日志切入点 在注解的位置切入代码
*/
@Pointcut("@annotation(design.model.business.utils.annotation.OperationLogAnnotation)")
public void operationLogAspect() {
}
@AfterReturning(returning = "result", value = "operationLogAspect()")
public void insertOperationLog(JoinPoint joinPoint, Object result) {
logger.info("切面日志");
try {
// 获取RequestAttributs
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
// 从获取RequestAttributes中获取HttpServletRequest的信息
HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
// Map<String, Object> map = (Map<String, Object>) result;
UserOperationLogEntity userOperationLogEntity = new UserOperationLogEntity();
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
OperationLogAnnotation annotation = method.getAnnotation(OperationLogAnnotation.class);
if (null != annotation) {
userOperationLogEntity.setModel(annotation.modul());
userOperationLogEntity.setBehaviorType(annotation.type());
userOperationLogEntity.setDescription(annotation.desc());
}
userOperationLogEntity.setUserCode(System.currentTimeMillis() +"");
userOperationLogEntity.setUserName(System.currentTimeMillis() + "D");
userOperationLogEntity.setId(UuidUtils.getUuId());
userOperationLogEntity.setOperationTime(sdf.format(new Date()));
userOperationLogEntity.setIpAddr(request.getRemoteHost());
userOperationLogEntity.setUrl(request.getRequestURL().toString());
logger.info("[{}]", JSON.toJSONString(userOperationLogEntity));
operationLogMapper.insert(userOperationLogEntity);
}catch (Exception e) {
e.printStackTrace();
logger.error("操作日志失败: {}", e.toString());
}
}
}
import java.util.HashMap;
import java.util.Map;
public interface OperationModuleContains {
String MODULE_BUSINESS = "business";
String MODULE_MANAGE = "manage";
String MODULE_GATEWAY = "gateway";
public interface OperationTypeContains {
String LOGIN = "登录操作";
String INSERT = "新增操作";
String UPDATE = "更新操作";
String DELETE = "删除操作";
String QUERY = "查询操作";
String EXPORT = "导出操作";
String IMPORT = "导入操作";
}
}