刚刚开通了一个公众号,会分享一些技术博客和自己觉得比较好的项目,同时会更新一些自己使用的工具和图书资料,后面会整理一些面试资料进行分享,觉得有兴趣的可以关注一下。
背景
最近的工作需求需要记录一下操作日志,什么人什么时间做的什么事情。在此分享一下。项目的认证使用的是OAUTH2认证
,会从认证服务器请求回来一个JWT TOKEN
,项目验证Token
并且判断是否有权限,以此为基础。
实现
方案
为防止代码入侵业务,肯定是需要使用AOP
来进行操作的。设置下切面和切点就可以了,最主要的是需要在切面的方法里找到当前的请求路径,还要获取请求的用户信息,请求的具体方法就可以用AOP
的JoinPoint
来获取就可以了。
实际上
Spring Boot
已经提供了两个工具类来实现这两个需求。RequestContextHolder
来获取具体的请求信息ServletRequestAttributes
,SecurityContextHolder
可以获取当前的用户验证信息。
代码
- 切点使用注解
public @interface RecordLog {
}
- 切面
@Aspect
@Component
public class RecordLogAspect {
@Resource
private RecordLogMapper recordLogMapper;
@Pointcut("@annotation(RecordLog)")
public void pointcut(){}
@AfterReturning("pointcut()")
public void doAfter(JoinPoint joinPoint) {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = requestAttributes.getRequest();
String url = request.getRequestURL().toString();
String methodName = joinPoint.getSignature().getDeclaringTypeName()+"-->"
+joinPoint.getSignature().getName();
RecordLogEntity recordLogEntity = new RecordLogEntity();
recordLogEntity.setUrl(url);
recordLogEntity.setMethod(methodName);
recordLogEntity.setUserName(SecurityContextHolder.getContext().getAuthentication().getName());
recordLogEntity.setOpTime(LocalDateTime.now(ZoneId.of("Asia/Shanghai")));
recordLogMapper.insertRecordLog(recordLogEntity);
}
}
SecurityContextHolder.getContext().getAuthentication()
来获取了验证信息,.getName()
获取用户名。
这样就可以使用注解RecordLog
,哪个需要被记录,就放在哪个请求上即可,项目主要记录写操作,对于读操作没必要记录。