在SpringBoot中实现对项目中的各个操作记录操作日志,此方法是最简单的方法,这样的做法需要对项目中的命名规则进行规范,比如添加用add* 编辑用 update* 删除用delete*
package com.ljq.bookshop.aop;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.ljq.bookshop.pojo.LogInfo;
import com.ljq.bookshop.pojo.UserInfo;
import com.ljq.bookshop.service.LogInfoService;
import com.ljq.bookshop.util.IpUtil;
@Aspect
@Component
public class LogAspect {
@Autowired
private LogInfoService logInfoService;
/**
* 添加业务逻辑方法切入点
*/
@Pointcut("execution(* com.ljq.bookshop.service.*.add*(..))")
public void addServiceCall() {
}
/**
* 修改业务逻辑方法切入点
*/
@Pointcut("execution(* com.ljq.bookshop.service.*.update*(..))")
public void updateServiceCall() {
}
/**
* 删除业务逻辑方法切入点
* 此处拦截要拦截到具体的莫一个模块
* 如deleteUser方法。则删除user的时候会记录日志
*/
@Pointcut("execution(* com.ljq.bookshop.service.*.delete*(..))")
public void deleteServiceCall() {
}
/**
* 管理员添加操作日志(后置通知)
* @param joinPoint
* @param rtv
* @throws Throwable
*/
@AfterReturning(value="addServiceCall()", argNames="rtv", returning="rtv")
public void insertServiceCallCalls(JoinPoint joinPoint, Object rtv) throws Throwable{
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
UserInfo currentUser = (UserInfo) request.getSession().getAttribute("user");
//判断参数
if(joinPoint.getArgs() == null){
return;
}
//获取方法名
//String methodName = joinPoint.getSignature().getName();
String className = joinPoint.getArgs()[0].getClass().getName();
//获取操作内容
className = className.substring(className.lastIndexOf(".") + 1);
String opContent = adminOptionContent(joinPoint.getArgs(), "添加");
//创建日志对象
LogInfo log = new LogInfo();
log.setModule(className.toLowerCase());
if(currentUser==null) {
log.setUserName("user");
}else {
log.setUserName(currentUser.getUsername());
}
//操作内容
log.setContent(opContent);
//操作
log.setOperation("添加");
log.setIp(IpUtil.getIpAddr(request));
logInfoService.insertLog(log);
}
/**
* 管理员修改操作日志(后置通知)
* @param joinPoint
* @param rtv
* @throws Throwable
*/
@AfterReturning(value="updateServiceCall()", argNames="rtv", returning="rtv")
public void updateServiceCallCalls(JoinPoint joinPoint, Object rtv) throws Throwable{
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
UserInfo currentUser = (UserInfo) request.getSession().getAttribute("user");
//判断参数
if(joinPoint.getArgs() == null){
return;
}
//获取方法名
String className = joinPoint.getArgs()[0].getClass().getName();
className = className.substring(className.lastIndexOf(".") + 1);
//获取操作内容
String opContent = adminOptionContent(joinPoint.getArgs(), "修改");
LogInfo log = new LogInfo();
log.setModule(className.toLowerCase());
if(currentUser==null) {
log.setUserName("user");
}else {
log.setUserName(currentUser.getUsername());
}
//操作
log.setContent(opContent);
log.setOperation("修改");
log.setIp(IpUtil.getIpAddr(request));
//添加日志
logInfoService.insertLog(log);
}
/**
* 管理员删除操作日志(后置通知)
* @param joinPoint
* @param rtv
* @throws Throwable
*/
@AfterReturning(value="deleteServiceCall()", argNames="rtv", returning="rtv")
public void deleteServiceCallCalls(JoinPoint joinPoint, Object rtv) throws Throwable{
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
UserInfo currentUser = (UserInfo) request.getSession().getAttribute("user");
//判断参数
if(joinPoint.getArgs() == null){
return;
}
//获取方法名
String className = joinPoint.getTarget().getClass().getName().toLowerCase();
try {
className=className.substring(0,className.indexOf("serviceimpl"));
className = className.substring(className.lastIndexOf(".") + 1);
}catch(Exception e) {
e.printStackTrace();
}
//获取操作内容
String opContent = "ID:"+joinPoint.getArgs()[0].toString()+"->删除";
LogInfo log = new LogInfo();
log.setModule(className);
if(currentUser==null) {
log.setUserName("user");
}else {
log.setUserName(currentUser.getUsername());
}
//操作
log.setContent(opContent);
log.setOperation("删除");
log.setIp(IpUtil.getIpAddr(request));
//添加日志
logInfoService.insertLog(log);
}
/**
* 使用Java反射来获取被拦截方法(insert、update)的参数值, 将参数值拼接为操作内容
*/
private String adminOptionContent(Object[] args, String type) throws Exception {
if (args == null) {
return null;
}
StringBuffer sb = new StringBuffer();
Object info = args[0];
String className = info.getClass().getName();
className = className.substring(className.lastIndexOf(".") + 1);
sb.append(type+className+" 属性名和值:");
// 获取对象的所有方法
Method[] methods = info.getClass().getDeclaredMethods();
// 遍历方法,判断get方法
for (Method method : methods) {
String methodName = method.getName();
// 判断是不是get方法
if (methodName.indexOf("get") == -1) {
continue;// 不处理
}
Object rsValue = null;
try {
// 调用get方法,获取返回值
rsValue = method.invoke(info);
if (rsValue == null) {
continue;
}
} catch (Exception e) {
continue;
}
// 将值加入内容中
sb.append(" " + methodName.substring(3) + "-->" + rsValue + " ");
}
return sb.toString();
}
}
登录日志需要在登录后添加如下代码:
saveLog(user.getUsername(), request, session);
以下是具体的代码
/**
* 保存日志信息
* @param userName
* @param request
* @param session
* @throws Exception
*/
private void saveLog(String userName, HttpServletRequest request, HttpSession session) throws Exception {
// 加入登陆日志
String uri = request.getRequestURI();
String contextPath=session.getServletContext().getContextPath();
uri = StringUtils.remove(uri, contextPath+"/");
LogInfo log = new LogInfo();
log.setUserName(userName);
log.setIp(IpUtil.getIpAddr(request));
log.setOperation("登录");
log.setContent(uri);
logInfoService.insertLog(log);
}