一、背景
接到一个需求,记录每个用户,在系统进行的修改、添加和删除的操作记录。
二、具体实现
日志记录,与主业务没有直接联系,不进行业务处理,故符合spring aop面向切面的编程思想。所以采用aop,来完成这一任务。
废话少说,直接上代码,代码参考了其他博主的文章,并结合实际情况进行修改。
@Aspect
@Component
@Slf4j
@Order(value = 3)//项目启动自动执行顺序
public class ThirdApiRequestLogAspect{
ObjectMapper objectMapper = new ObjectMapper();
@Autowired
private OperationLogMapper operationLogMapper;
@Autowired
private UserPersistenceService userPersistenceService;
//过滤不保存的方法
final String [] filtration = {"DeviceApiController.searchDeviceList"};
public ThirdApiRequestLogAspect() {
log.info("初始化接口日志切面类...");
}
//切入点,该切入点下的方法都会执行该切面方法
@Pointcut("execution(public * com.it.foundwater.controller.*.*(..))")
public void controllerInteceptor() {
}
//环绕通知/环绕增强
@Around("controllerInteceptor()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Date start = new Date();
Object o = null;
try {
//操作日志实体
OperationLog sysLog = new OperationLog();
ApiOperation syslog1 = method.getAnnotation(ApiOperation.class);
if(syslog1!=null) {
//注解上的描述
sysLog.setMethod(syslog1.value());
}
//请求的方法名
String clazzName = joinPoint.getTarget().getClass().getName();
Class<?> clazz = Class.forName(clazzName);
String clazzSimpleName = clazz.getSimpleName();
String methodName = signature.getName();
sysLog.setOperationDesc(clazzSimpleName+'.'+methodName);
//请求的参数
String[] parameterNames = ((MethodSignature) joinPoint.getSignature()).getParameterNames();
StringBuilder sb = null;
if (Objects.nonNull(parameterNames)) {
sb = new StringBuilder();
for (int i = 0; i < parameterNames.length; i++) {
Object param = joinPoint.getArgs()[i] != null ? joinPoint.getArgs()[i] : "";
if (StringUtils.isNotEmpty(param.toString()) && !"request".equals(parameterNames[i]) && !"response".equals(parameterNames[i])
&& !"modelMap".equals(parameterNames[i])) {
if (param instanceof Integer) {
sb.append(parameterNames[i] + ":" + param + "; ");
} else if (param instanceof String) {
sb.append(parameterNames[i] + ":" + param + "; ");
} else if (param instanceof Double) {
sb.append(parameterNames[i] + ":" + param + "; ");
} else if (param instanceof Float) {
sb.append(parameterNames[i] + ":" + param + "; ");
} else if (param instanceof Long) {
sb.append(parameterNames[i] + ":" + param + "; ");
} else if (param instanceof Boolean) {
sb.append(parameterNames[i] + ":" + param + "; ");
} else if (param instanceof Date) {
sb.append(parameterNames[i] + ":" + param + "; ");
} else if (param instanceof Timestamp) {
sb.append(parameterNames[i] + ":" + param + "; ");
} else {
sb.append(parameterNames[i] + ":" + getString(param) + "; ");
}
}
}
}
sb = sb == null ? new StringBuilder() : sb;
sysLog.setParams(sb.toString());
//设置IP地址
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
User user = null;
if(StringUtils.isNotEmpty(methodName)&&"login".equals(methodName)) {
//为登录接口没有session
user = this.getDecodeUserName(request,1,sb.toString());
}else {
user = this.getDecodeUserName(request,0,"");
}
sysLog.setIp(IpAddressUtil.getIpAddr(request));
sysLog.setUserName(user==null?null:user.getName());
sysLog.setCreateTime(LocalDateTime.now());
sysLog.setLoginName(user==null?null:user.getLoginName());
log.debug("interface request startTime " + start.getTime());
o = joinPoint.proceed();
String response = objectMapper.writeValueAsString(o);
//get查询请求不记录
if("GET".equals(request.getMethod())) {
log.info("查询请求不记录:"+request.getMethod());
return o;
}
if(Arrays.asList(filtration).contains(sysLog.getOperationDesc())) {
log.info("该请求不记录:"+sysLog.getOperationDesc());
return o;
}
sysLog.setReturnResult(response);
sysLog.setTimeMin(System.currentTimeMillis() - start.getTime());
log.debug(getString(sysLog));
//保存系统日志
operationLogMapper.insert(sysLog);
return o;
} catch (Exception e) {
// TODO: handle exception
log.error("保存系统日志失败"+e);
o = joinPoint.proceed();
}
return o;
}
//各个项目获取用户信息不同,根据自己项目进行修改
public User getDecodeUserName(HttpServletRequest request,Integer type,String params) {
User user = null;
Long userId = null;
String loginName=null;
try {
if(null!=type&&0==type) {
userId = (Long) request.getSession().getAttribute("CURRENT_USER_ID");
}else if(null!=type&&1==type) {
String p = params;
String p1 = p.substring(p.indexOf("[")+1,p.indexOf("]"));
System.out.println(p1);
String [] p2 = p1.split("\\|");
for(String p3:p2) {
if(p3.indexOf("loginName")>=0) {
loginName=p3.substring(p3.indexOf("=")+1);
}
}
}
//过滤没有token时的false情况
if(null!=userId) {
user = userPersistenceService.getById(userId);
return user;
}
//登录接口
if(StringUtils.isNotEmpty(loginName)) {
user = userPersistenceService.findUserByLoginName(loginName);
}
} catch (Exception e) {
log.error("获取用户名失败"+e.getMessage(), e);
}
return user;
}
public static String getString(Object o) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
StringBuffer sb = new StringBuffer();
sb.append("entity[");
Field[] farr = o.getClass().getDeclaredFields();
for (Field field : farr) {
try {
field.setAccessible(true);
if (field.get(o)!=null) {
sb.append(field.getName());
sb.append("=");
if (field.get(o) instanceof Date) {
// 日期的处理
sb.append(sdf.format(field.get(o)));
} else {
sb.append(field.get(o));
}
sb.append("|");
}
} catch (Exception e) {
e.printStackTrace();
}
}
sb.append("]");
return sb.toString();
}
}