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;
}

 

posted on 2022-03-16 11:29  技术猫猫  阅读(234)  评论(0编辑  收藏  举报

导航