springboot—spring aop realizes the storage of system operation log records to the database

Solution: Use spring's aop technology to switch to custom annotations, analyze parameters for different annotation flags, and record logs. The
disadvantage is to take the annotation flags separately for each different annotation flag and obtain parameters for logging output.

  1. Dependent dependencies
org.springframework.boot spring-boot-starter-aop


Add such a configuration in the application.properties file spring.aop.auto = true // This configuration does not add in my example and works normally
2. Create an entity class
public class SysLog implements Serializable {
private Long id;

private String username; //用户名

private String operation; //操作

private String method; //方法名

private String params; //参数

private String ip; //ip地址

private Date createDate; //操作时间
//创建getter和setter方法

}
3. Use spring's aop technology to switch to custom annotations, so first create a custom annotation class
import java.lang.annotation. *;

/**

  • Custom annotation class
    * /
    @Target (ElementType.METHOD) // The target position where the annotation is placed, METHOD is
    annotable at the method level @Retention (RetentionPolicy.RUNTIME) // The stage at which the annotation is executed
    @Documented // Generate the document
    public @interface MyLog {
    String value () default “”;
    }
  1. 创建aop切面实现类
    import com.alibaba.fastjson.JSON;
    import com.qfedu.rongzaiboot.annotation.MyLog;
    import com.qfedu.rongzaiboot.entity.SysLog;
    import com.qfedu.rongzaiboot.service.SysLogService;
    import com.qfedu.rongzaiboot.utils.HttpContextUtils;
    import com.qfedu.rongzaiboot.utils.IPUtils;
    import com.qfedu.rongzaiboot.utils.ShiroUtils;
    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.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

/**

  • System log: Aspect processing class
    * /
    @Aspect
    @Component
    public class SysLogAspect {

    @Autowired
    private SysLogService sysLogService;

    // Define the pointcut @Pointcut
    // cut in the code
    @Pointcut ("@ annotation (com.qfedu.rongzaiboot.annotation.MyLog)")
    public void logPoinCut () {
    }

    // Section configuration notification
    @AfterReturning ("logPoinCut ()")
    public void saveSysLog (JoinPoint joinPoint) {
    System.out.println (" Slice .....");
    // Save log
    SysLog sysLog = new SysLog ();

     //从切面织入点处通过反射机制获取织入点处的方法
     MethodSignature signature = (MethodSignature) joinPoint.getSignature();
     //获取切入点所在的方法
     Method method = signature.getMethod();
    
     //获取操作
     MyLog myLog = method.getAnnotation(MyLog.class);
     if (myLog != null) {
         String value = myLog.value();
         sysLog.setOperation(value);//保存获取的操作
     }
    
     //获取请求的类名
     String className = joinPoint.getTarget().getClass().getName();
     //获取请求的方法名
     String methodName = method.getName();
     sysLog.setMethod(className + "." + methodName);
    
     //请求的参数
     Object[] args = joinPoint.getArgs();
     //将参数所在的数组转换成json
     String params = JSON.toJSONString(args);
     sysLog.setParams(params);
    
     sysLog.setCreateDate(new Date());
     //获取用户名(可通过request去获取到usertoken)
     sysLog.setUsername(ShiroUtils.getUserEntity().getUsername());
     //获取用户ip地址
     HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
     sysLog.setIp(IPUtils.getIpAddr(request));
    
     //调用service保存SysLog实体类到数据库
     sysLogService.save(sysLog);
    

    }

}
5. Next, you can add aop's custom annotation to the method that needs to be monitored. The
format is @ + Custom annotation class name @MyLog
// For example, add a annotation
@RestController
@RequestMapping ("/ sys to the method of the contoller class / menu ")
public class SysMenuController extends AbstractController {

@Autowired
private SysMenuService sysMenuService;

@MyLog(value = "删除菜单记录")  //这里添加了AOP的自定义注解
@PostMapping("/del")
public R deleteBatch(@RequestBody Long[] menuIds) {
    for (Long menuId : menuIds) {
        if (menuId <= 31) {
            return R.error("系统菜单,不能删除");
        }
    }
    sysMenuService.deleteBatch(menuIds);

    return R.ok("删除成功");
}

}
6.网上找的utils(可参考)
public class HttpContextUtils {
public static HttpServletRequest getHttpServletRequest() {
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
}
}

import javax.servlet.http.HttpServletRequest;

public class IPUtils {
public static String getIpAddr(HttpServletRequest request) {
String ip = request.getHeader(“x-real-ip”);

if (ip == null || ip.length() == 0 || “unknown”.equalsIgnoreCase(ip)) {
ip = request.getHeader(“x-forwarded-for”);
if (ip != null) {
ip = ip.split(",")[0].trim();
}
}

if (ip == null || ip.length() == 0 || “unknown”.equalsIgnoreCase(ip)) {
ip = request.getHeader(“Proxy-Client-IP”);
}

if (ip == null || ip.length() == 0 || “unknown”.equalsIgnoreCase(ip)) {
ip = request.getHeader(“WL-Proxy-Client-IP”);
}

if (ip == null || ip.length() == 0 || “unknown”.equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}

return ip;
}
}
7. After executing the above method, the record will be saved to the database

Published an original article · Like1 · Visits 36

Guess you like

Origin blog.csdn.net/qq_37523371/article/details/105610512