问题描述
ssm需要实现用户操作日志记录,实现方式为AOP注解,自定义操作模块信息,操作成功或者失败,记录在数据库中。
步骤
1.新建日志数据库sys_log(MySQL)
2.创建该表的POJO类,mapper映射,这里省略
3.创建注解
import java.lang.annotation.*;
/**
*自定义注解 拦截Controller
*/
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemLog {
String module() default ""; //模块名称 系统管理-用户管理-列表页面
String methods() default ""; //新增用户
String description()default "";
}
4.配置拦截类
import java.lang.reflect.Method;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.logging.log4j.LogManager;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
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 org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.apache.logging.log4j.Logger;
@Aspect
@Component
public class SysLogAspect {
private Logger logger = LogManager.getLogger("SysLogAspect");
@Autowired
private SysLogMapper logMapper;
/**
* Controller层切点 注解拦截
*/
@Pointcut("@annotation(com.tantela.config.logaop.SystemLog)")
public void controllerAspect(){
System.out.println("切入点");
}
@Around("controllerAspect()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
SysLog log=new SysLog();
//获取登录用户账户
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
HttpSession session=request.getSession();
log.setAccountname(ToolUtil.user(session));
//获取系统时间
log.setCreateTime(new Date());
//获取系统ip,这里用的是我自己的工具类,可自行网上查询获取ip方法
log.setUserIp(ToolUtil.getIpAddr(request));
//long start = System.currentTimeMillis();//模块开始执行时间
// 拦截的实体类,就是当前正在执行的controller
Object target = pjp.getTarget();
// 拦截的方法名称。当前正在执行的方法
String methodName = pjp.getSignature().getName();
// 拦截的方法参数
Object[] args = pjp.getArgs();
// 拦截的放参数类型
Signature sig = pjp.getSignature();
MethodSignature msig = null;
if (!(sig instanceof MethodSignature)) {
throw new IllegalArgumentException("该注解只能用于方法");
}
msig = (MethodSignature) sig;
Class[] parameterTypes = msig.getMethod().getParameterTypes();
Object object = null;
// 获得被拦截的方法
Method method = null;
try {
method = target.getClass().getMethod(methodName, parameterTypes);
} catch (NoSuchMethodException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (SecurityException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if (null != method) {
// 判断是否包含自定义的注解,说明一下这里的SystemLog就是我自己自定义的注解
if (method.isAnnotationPresent(SystemLog.class)) {
SystemLog systemlog = method.getAnnotation(SystemLog.class);
log.setModule(systemlog.module());
log.setMethods(systemlog.methods());
try {
object = pjp.proceed();
//long end = System.currentTimeMillis();
//log.setRSPONSE_DATA(""+(end-start)); //计算响应时间
log.setDescription("执行成功!");
//保存进数据库
logMapper.insertSelective(log);
} catch (Throwable e) {
// long end = System.currentTimeMillis();
// log.setRSPONSE_DATA(""+(end-start));
log.setDescription("执行失败");
logMapper.insertSelective(log);
}
} else {//没有包含注解
object = pjp.proceed();
}
} else { //不需要拦截直接执行
object = pjp.proceed();
}
return object;
}
}
最后,使用
@SystemLog(module="登录",methods="后台管理系统登录")
@ResponseBody
@RequestMapping(value = "/login.do", method = RequestMethod.POST)
public String login() {
}
5.在springMVC.xml中配置中加入代码,使注解生效。
注意:如果在SpringBoot下,省略此步骤
<!-- 系统日志的注解生效 -->
<aop:aspectj-autoproxy proxy-target-class="true" />
<bean id="logAopAction" class="com.tantela.logaop.SysLogAspect"/>
说明
内容仅作参考,还有很多不完善的地方。