毕业设计篇1——SpringBoot AOP 实现记录操作日志、异常日志简单示例

学习目标:

Spring中AOP的注解实现方式简单示例
当我们在操作某些功能的时候有可能会发生异常,但是每次发生异常要定位找到原因我们都要到服务器去查询日志才能找到,而且也不能对发生的异常进行统计,从而改进我们的项目
——增加记录操作日志和异常日志的功能。

今天我们就用Spring AOP的思想来实现这个小功能:


学习内容:

下面是写的一个小Demo,供大家参考练习:
Aspect.java

package com.example.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;

/**
 * @program: springstudy
 * @description:
 * @author: 
 * @create: 2021-04-05 14:57
 **/

/**
 * 切面
 * 通知+切点的集合,定义在什么地方什么时间做什么事情。
 */
@org.aspectj.lang.annotation.Aspect   //定义一个切面
@Component
public class Aspect {

    /**
     * 切点:定义了在“什么地方”进行切入,哪些连接点会得到通知
     * execution :切点表达式
     */
    @Pointcut("execution(* com.example.controller.*.*(..))")
    public void logPointCut(){}


    /**
     * 通知方法在目标方法调用之前执行
     */
    @Before("logPointCut()")
    public void beforeAdvice() {
        System.out.println("beforeAdvice...");
    }

    /**
     * 通知方法会在目标方法返回或抛出异常后调用
     */
    @After("logPointCut()")
    public void afterAdvice() {
        System.out.println("afterAdvice...");
    }

    @Around("logPointCut()")
    public void aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) {
        System.out.println("before");
        try {
            proceedingJoinPoint.proceed();
        } catch (Throwable t) {
            t.printStackTrace();
        }
        System.out.println("after");
    }

    @AfterReturning(pointcut = "logPointCut()", returning = "jsonResult")
    public void doAfterReturning(JoinPoint joinPoint, Object jsonResult) {
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String method = attributes.getRequest().getMethod();
        System.out.println("(1)方法名:"+className + "." + methodName );
        System.out.println("(2)方法的返回值:"+ jsonResult);
        System.out.println("(3)请求类型:" + method);
    }

    @AfterThrowing(value = "logPointCut()", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint, Exception e) {
        System.out.println("e.getMessage():" + e.getMessage());
    }
}

UserController.java

package com.example.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * @program: springstudy
 * @description:
 * @author: 
 * @create: 2021-04-05 15:04
 **/

@RestController
public class UserController {

    @RequestMapping(value = {"/user","/"})
    public String sayHello() throws Exception{
        System.out.println("User");
        return "admin";
    }
}

测试结果
在这里插入图片描述


下面是增加了自定义操作日志注解的方式实现,供大家参考:

自定义操作日志注解——OperLog.java

package com.example;
import java.lang.annotation.*;

@Target(ElementType.METHOD) //注解放置的目标位置,METHOD是可注解在方法级别上
@Retention(RetentionPolicy.RUNTIME) //注解在哪个阶段执行
@Documented
public @interface OperLog {
    String operModul() default ""; // 操作模块
    String operType() default "";  // 操作类型
    String operDesc() default "";  // 操作说明
 }

切面类——OperLogAspect.java

package com.example;
import com.alibaba.fastjson.JSON;
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.Value;
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.HashMap;
import java.util.Map;

/**
 * @program: generate_code
 * @description: XXX
 * @author: 
 * @create: 2020-12-31 17:45
 **/

@Aspect
@Component
public class OperLogAspect {

     @Value("${version}")
     private String operVer;


    /**
     * 设置操作日志切入点 记录操作日志 在注解的位置切入代码
     */
    @Pointcut("@annotation(com.example.OperLog)")
    public void operLogPointCut(){}

    @AfterReturning(pointcut = "operLogPointCut()", returning = "keys")
    public void saveOperLog(JoinPoint joinPoint, Object keys){
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
        OperationLog  operationLog = new OperationLog();
        operationLog.setOperId("123"); // 主键ID

        //从切面织入点处通过反射机制获取织入点的方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();

        //获取切入点的方法
        Method method = signature.getMethod();

        //获取操作
        OperLog annotation = method.getAnnotation(OperLog.class);


        if(null != annotation){
            String operModul = annotation.operModul();  //操作模块
            String operType = annotation.operType();    //操作类型
            String operDesc = annotation.operDesc();   //操作描述

            operationLog.setOperModul(operModul);

            operationLog.setOperType(operType);

            operationLog.setOperDesc(operDesc);
        }
        
        //获取请求的类
        String className = joinPoint.getTarget().getClass().getName();

        //获取请求的方法名
        String methodName = method.getName();
        methodName = className + "." +methodName;

        operationLog.setOperMethod(methodName);

        //获取请求的参数
        Map<String, String> rtnMap = converMap(request.getParameterMap());

        //将参数所在的数组转换成json
        String params = JSON.toJSONString(rtnMap);

        operationLog.setOperRequestParam(params);      //请求参数

        operationLog.setOperRespParam(JSON.toJSONString(keys)); // 返回结果

        operationLog.setOperUserId("200000001");    //请求用户ID

        operationLog.setOperUserName("admin");    //请求用户名称

        operationLog.setOperIp("127.0.0.1");   //请求IP

        operationLog.setOperUri(request.getRequestURI()); // 请求URI


        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        operationLog.setOperCreateTime(df.format(new Date())); // 创建时间

        operationLog.setOperVer(operVer);   //操作版本

        System.out.println(operationLog.toString());
    }

    /**
     * 转换request 请求参数
     * @param paramMap
     * @return
     */
    public Map<String,String> converMap(Map<String,String[]> paramMap){
        Map<String,String > rtnMap = new HashMap<String,String>();
        for(String key:paramMap.keySet()){
            rtnMap.put(key,paramMap.get(key)[0]);
        }
        return rtnMap;

    }
}

OperationLog.java

package com.example;

/**
 * @program: generate_code
 * @description: X
 * @author:
 * @create: 2020-12-31 17:55
 **/
public class OperationLog {
    private String operId;

    private String operRequestParam;  //请求参数

    private String operRespParam;   //返回结果

    private String operUserId;   //请求用户ID

    private String operUserName;   //请求用户名称

    private String operIp;    //请求IP

    private String operModul;   //操作模块

    private String operType;   //操作类型

    private String operDesc;   //操作描述

    private String operMethod;  //请求方法

    private String operUri;   //请求URI

    private String operCreateTime;  //创建时间

    private String operVer;  //操作版本

    public String getOperId() {
        return operId;
    }

    public void setOperId(String operId) {
        this.operId = operId;
    }

    public String getOperRequestParam() {
        return operRequestParam;
    }

    public void setOperRequestParam(String operRequestParam) {
        this.operRequestParam = operRequestParam;
    }

    public String getOperRespParam() {
        return operRespParam;
    }

    public void setOperRespParam(String operRespParam) {
        this.operRespParam = operRespParam;
    }

    public String getOperUserId() {
        return operUserId;
    }

    public void setOperUserId(String operUserId) {
        this.operUserId = operUserId;
    }

    public String getOperUserName() {
        return operUserName;
    }

    public void setOperUserName(String operUserName) {
        this.operUserName = operUserName;
    }

    public String getOperIp() {
        return operIp;
    }

    public void setOperIp(String operIp) {
        this.operIp = operIp;
    }

    public String getOperModul() {
        return operModul;
    }

    public void setOperModul(String operModul) {
        this.operModul = operModul;
    }

    public String getOperType() {
        return operType;
    }

    public void setOperType(String operType) {
        this.operType = operType;
    }

    public String getOperDesc() {
        return operDesc;
    }

    public void setOperDesc(String operDesc) {
        this.operDesc = operDesc;
    }

    public String getOperMethod() {
        return operMethod;
    }

    public void setOperMethod(String operMethod) {
        this.operMethod = operMethod;
    }

    public String getOperUri() {
        return operUri;
    }

    public void setOperUri(String operUri) {
        this.operUri = operUri;
    }

    public String getOperCreateTime() {
        return operCreateTime;
    }

    public void setOperCreateTime(String operCreateTime) {
        this.operCreateTime = operCreateTime;
    }

    public String getOperVer() {
        return operVer;
    }

    public void setOperVer(String operVer) {
        this.operVer = operVer;
    }

    @Override
    public String toString() {
        return "OperationLog{" +
                "操作ID='" + operId + '\'' +
                ", 请求参数='" + operRequestParam + '\'' +
                ", 返回结果='" + operRespParam + '\'' +
                ", 请求用户ID'" + operUserId + '\'' +
                ", 请求用户名称='" + operUserName + '\'' +
                ", 请求IP='" + operIp + '\'' +
                ", 操作模块='" + operModul + '\'' +
                ", 操作类型='" + operType + '\'' +
                ", 操作描述='" + operDesc + '\'' +
                ", 请求方法='" + operMethod + '\'' +
                ", 请求URI='" + operUri + '\'' +
                ", 创建时间='" + operCreateTime + '\'' +
                ", 操作版本='" + operVer + '\'' +
                '}';
    }
}

Result.java

package com.example.result;

/**
 * @program: generate_code
 * @description: XXX
 * @author: 
 * @create: 2021-01-01 14:16
 **/
public class Result {

    private String code;

    private String msg;

    private Object data;

    public Result() {
    }

    public Result(String code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public Result(String code, String msg, Object data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

UserController.java

package com.example.controller;

import com.example.OperLog;
import com.example.result.Result;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

/**
 * @program: generate_code
 * @description: XXX
 * @author: 
 * @create: 2021-01-01 14:11
 **/

@RequestMapping(value = "/user")
@RestController
public class UserController {

    @RequestMapping(value = "/add",method = RequestMethod.GET)
    @OperLog(operModul = "用户管理",operType = "ADD",operDesc = "获取用户信息")
    public Result  getUserList(){
        return new Result("200","操作成功",null);
    }
}

测试

OperationLog{操作ID=‘123’, 请求参数=’{}’, 返回结果=’{“code”:“200”,“msg”:“操作成功”}’, 请求用户ID’200000001’, 请求用户名称=‘admin’, 请求IP=‘118.31.187.5’, 操作模块=‘用户管理’, 操作类型=‘ADD’, 操作描述=‘获取用户信息’, 请求方法=‘com.example.controller.UserController.getUserList’, 请求URI=’/user/add’, 创建时间=‘2021-04-05 21:36:52’, 操作版本=‘123’}

在这里插入图片描述



本篇文章到这里就基本结束了,如果这篇文章对你有帮助,希望大家能留下你的点赞、 关注、 分享、 留言❤️❤️❤️


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小Java开发者

“是一种鼓励,你懂的”

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值