3.使用注解实现记录接口日志
功能如下:要求平台登录用户记录操作日志,记录增删改以及接口类型。
思路是在需要记录的地方添加注解,之后再用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; }