Aop记录用户操作日志相关依赖
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.5</version>
</dependency>
自定义注解
import java.lang.annotation.*;
/**
* 自定义日志注解
*
* @author zz
* @since 2020/6/16
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OperLog {
String value() default "";
}
创建数据库表和实体
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;
/**
* 日志
*
* @author zz
* @since 2020/6/16
*/
@Setter
@Getter
@Entity
@Table(name = "sys_log")
public class SysLog {
@Id
private String id;
private String username;
private String operation;
private Integer time;
private String method;
private String params;
private String ip;
private Date operationTime;
private String url;
}
dao层接口
import org.springframework.data.jpa.repository.JpaRepository;
/**
* 日志dao接口
*
* @author zz
* @since 2020/6/16
*/
public interface SysLogDao extends JpaRepository<SysLog,Integer> {
}
访问指定接口时生成日志,保存日志
/**
* 根据切点表达式在访问指定接口时生成日志,保存日志
*
* @author zz
* @since 2020/6/16
*/
@Aspect
@Component
@Slf4j
public class OperLogAspect {
/**
* 设置操作日志切入点 记录操作日志
*/
@Autowired
private SysLogDao sysLogDao;
/**
* 在注解的位置切入代码
* 表示匹配com.baidu.well.controller包下的所有方法
*/
@Pointcut("execution(* com.baidu.well.controller.*.*(..))")
public void operLogPoinCut() {
}
/**
* 正常返回通知,拦截用户操作日志,连接点正常执行完成后执行, 如果连接点抛出异常,则不会执行
*
* @param joinPoint 切入点
* @param keys 返回结果
*/
@AfterReturning(value = "operLogPoinCut()", returning = "keys")
public void saveOperLog(JoinPoint joinPoint, Object keys) {
long beginTime = System.currentTimeMillis();
// 获取RequestAttributes
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
// 从获取RequestAttributes中获取HttpServletRequest的信息
HttpServletRequest request = (HttpServletRequest) requestAttributes
.resolveReference(RequestAttributes.REFERENCE_REQUEST);
SysLog sysLog = new SysLog();
String id = UUID.randomUUID().toString().replace("-", "");
sysLog.setId(id);
try {
// 从切面织入点处通过反射机制获取织入点处的方法
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
// 获取切入点所在的方法
Method method = signature.getMethod();
// 获取操作
OperLog opLog = method.getAnnotation(OperLog.class);
if (opLog != null) {
String value = opLog.value();
sysLog.setOperation(value);
}
// 获取请求的类名
String className = joinPoint.getTarget().getClass().getName();
// 获取请求的方法名
String methodName = method.getName();
methodName = className + "." + methodName + "()";
// 请求方法
sysLog.setMethod(methodName);
String params = getParams(joinPoint, method);
sysLog.setParams(params);
// 请求用户名称
String username = getUserName(request);
sysLog.setUsername(username);
// 访问的url
sysLog.setUrl(request.getRequestURL().toString());
// 请求IP
sysLog.setIp(IPUtils.getIpAddr(request));
// 创建时间
sysLog.setOperationTime(new Date());
sysLog.setTime((int) (System.currentTimeMillis() - beginTime));
// 保存日志
sysLogDao.save(sysLog);
} catch (Exception e) {
e.printStackTrace();
}
}
// 获取请求的参数名称
private String getParams(JoinPoint joinPoint, Method method) {
// 请求的方法参数值
Object[] args = joinPoint.getArgs();
// 请求的方法参数名称
LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
String[] paramNames = u.getParameterNames(method);
String params = null;
if (args != null && paramNames != null) {
for (int i = 0; i < args.length; i++) {
params += " " + paramNames[i] + ": " + args[i];
}
}
return params;
}
// 获取当前操作的用户名称
private String getUserName(HttpServletRequest request) {
String name = request.getUserPrincipal().getName();
String substring = name.substring(5, name.length() - 3);
String[] split = substring.split(",");
String username = null;
for (int i = 0; i < split.length; i++) {
String s = split[3];
username = s.substring(7, s.length() - 1);
}
return username;
}
}
获取Ip地址的工具类
import javax.servlet.http.HttpServletRequest;
/**
* 获取请求的Ip地址
*
* @author zz
* @since 2020/6/16
*/
public class IPUtils {
private static final String X_FORWARDED_FOR = "x-forwarded-for";
public static String getIpAddr(HttpServletRequest request) {
String ip = request.getHeader(X_FORWARDED_FOR);
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 "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
}
}
注意:在Controller接口上添加自定的注解@OperLog,实现记录用户的操作日志SpringBoot项目启动类添加包扫描的注解
@EnableAspectJAutoProxy(proxyTargetClass=true) 默认值就是true
@SpringBootApplication
@ComponentScan("com.nec.wellness.*")
@EnableAspectJAutoProxy(proxyTargetClass=true)
public class WellnessDbApplication {
public static void main(String[] args) {
SpringApplication.run(WellnessDbApplication.class, args);
}
}
原文链接:https://blog.csdn.net/weixin_45068151/article/details/106809186