功能如下:要求平台登录用户记录操作日志,记录增删改以及接口类型。
思路是在需要记录的地方添加注解,之后再用aop监听此注解,将数据记录到数据表中。
具体如下:
建立自定义注解:
//在方法中生效
@Target({ElementType.METHOD})
//在运行过程中生效
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DistOperateLogAnnotation {
/** 接口类型 1-用户*/
DistOperateInterfaceTypeEnum interfaceType();
/** 操作类型 1:新增;2:修改;3:删除;*/
DistOperateTypeEnum operateType();
}
在接口上添加此注解:
//引用自定义注解
@DistOperateLogAnnotation(interfaceType = DistOperateInterfaceTypeEnum.USER, operateType = DistOperateTypeEnum.ADD)
@PostMapping(path = "/api/add")
public String add(@RequestBody User user) {
return "success";
}
添加aop监听自定义注解,因为要获取参数以及数据返回结果,因此要使用@Around:
@Slf4j
@Aspect
@Component
@Order
public class ApiInterceptor {
@Pointcut("@annotation(com.zxy.DistOperateLogAnnotation)")
public void distOperateLogAnnotation() {
}
/**
* 记录日志
*
* @author zhouxy
*/
@Around(value = "distOperateLogAnnotation()")
public Object after(ProceedingJoinPoint joinPoint) throws Throwable {
Object result = joinPoint.proceed();
addOperationLog(joinPoint);
return result;
}
private void addOperationLog(ProceedingJoinPoint joinPoint) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
DistOperateLogAnnotation reporter = signature.getMethod().getAnnotation(DistOperateLogAnnotation.class);
try {
//使用日志实体存储实体信息
OperationLog operateLog = new OperationLog();
Integer operationType = reporter.operateType().getCode();
//保存日志信息
Object[] args = joinPoint.getArgs();
Long dataId;
if (Objects.equals(operationType, DistOperateTypeEnum.ADD.getCode()) || Objects.equals(operationType, DistOperateTypeEnum.MODIFY.getCode())) {
//参数为对象(添加和修改)时,格式化为json
String jsonString = JSON.toJSONString(args[0]);
JSONObject json = JSONObject.parseObject(jsonString);
dataId = Long.valueOf(String.valueOf(json.containsKey("id") ? json.get("id") : json.get("sid")));
operateLog.setContent(jsonString);
} else if (Objects.equals(operationType, DistOperateTypeEnum.DELETE.getCode())) {
//参数为单个数据(删除)时
dataId = Long.valueOf(String.valueOf(args[0]));
} else {
throw new RuntimeException("日志类型不正确");
}
operateLog.setOperationType(operationType);
operateLog.setConfigType(reporter.interfaceType().getCode());
operateLog.setConfigId(dataId);
operateLog.setCreateTime(new Date());
operateLog.setCreatedBy(DistributionRequestContext.getUserNameKey());
operationLogMapper.insert(operateLog);
} catch (Exception e) {
log.error("添加失败", e);
}
}
}
实体类属性:
public class OperationLog implements Serializable {
private static final long serialVersionUID = 7677488183009369456L;
@Id
@Column(name = "`sid`")
private Long sid;
/**
* 接口类型
*/
@Column(name = "`config_type`")
private Integer configType;
/**
* 操作类型,1:新增;2:修改;3:删除;
*/
@Column(name = "`operation_type`")
private Integer operationType;
/**
* 表数据ID
*/
@Column(name = "`config_id`")
private Long configId;
/**
* 操作内容
*/
@Column(name = "`content`")
private String content;
/**
* 操作时间
*/
@Column(name = "`create_time`")
private Date createTime;
/**
* 操作人
*/
@Column(name = "`created_by`")
private String createdBy;
}