1、建包、创类、建数据库
2 、数据库对应实体类 PcOperateLog
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PcOperateLog {
private Integer id;
private String name;
private String time;
private String ip;
private String ipLocation;
private String record;
}
3、MyLog类
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定义注解记录系统操作日志
*/
//Target注解决定 MyLog 注解可以加在哪些成分上,如加在类身上,或者属性身上,或者方法身上等成分
@Target({ ElementType.PARAMETER, ElementType.METHOD })
//Retention注解括号中的"RetentionPolicy.RUNTIME"意思是让 MyLog 这个注解的生命周期一直程序运行时都存在
@Retention(RetentionPolicy.RUNTIME)
public @interface MyLog {
/**
* 日志内容
*/
String record() default "";
}
4、OperLogAspect类
package com.woniu.pc.aop;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.woniu.pc.entity.PcOperateLog;
import com.woniu.pc.mapper.PcOperateLogMapper;
import com.woniu.util.BaiduMapUtil;
import com.woniu.util.GetContext;
import com.woniu.util.JsonUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import com.woniu.pc.anno.MyLog;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import com.woniu.pc.service.impl.PcLoginLogServiceImpl;
/**
* 切面处理类,记录操作日志到数据库
*/
@Aspect
@Component
public class OperLogAspect {
@Autowired
private PcOperateLogMapper pcOperateLogMapper;
//为了记录方法的执行时间
ThreadLocal<Long> startTime = new ThreadLocal<>();
/**
* 设置操作日志切入点,这里介绍两种方式:
* 1、基于注解切入(也就是打了自定义注解的方法才会切入)
* @Pointcut("@annotation(com.woniu.pc.anno.MyLog)")
* 2、基于包扫描切入
* @Pointcut("execution(public * org.wujiangbo.controller..*.*(..))")
*/
@Pointcut("@annotation(com.woniu.pc.anno.MyLog)")//在注解的位置切入代码
//@Pointcut("execution(public * com.woniu.pc.controller..*.*(..))")//从controller切入
public void operLogPoinCut() {
}
@Before("operLogPoinCut()")
public void beforMethod(JoinPoint point){
startTime.set(System.currentTimeMillis());
}
/**
* 设置操作异常切入点记录异常日志 扫描所有controller包下操作
*/
@Pointcut("execution(* com.woniu.pc.controller..*.*(..))")
public void operExceptionLogPoinCut() {
}
/**
* 正常返回通知,拦截用户操作日志,连接点正常执行完成后执行, 如果连接点抛出异常,则不会执行
*
* @param joinPoint 切入点
* @param result 返回结果
*/
@AfterReturning(value = "operLogPoinCut()", returning = "result")
public void saveOperLog(JoinPoint joinPoint, Object result) {
// 获取RequestAttributes
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
// 从获取RequestAttributes中获取HttpServletRequest的信息
HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
try {
// 从切面织入点处通过反射机制获取织入点处的方法
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
// 获取切入点所在的方法
Method method = signature.getMethod();
// 获取操作
MyLog myLog = method.getAnnotation(MyLog.class);
PcOperateLog pcOperateLog = new PcOperateLog();
if (myLog != null) {
//记录日志的操作内容
pcOperateLog.setRecord(myLog.record());
}
//获取操作者
Map userInfo = GetContext.getContext();
String username = (String)userInfo.get("username");
pcOperateLog.setName(username);
//获取ip地址
String ip = PcLoginLogServiceImpl.ip;
String fileName="js.txt";
String path="D:\\js\\";
String directoryPath = "D:\\js";
JSONObject jsonObject = new JSONObject();
jsonObject.put("ip", ip);
String json = null;
if(ip == "" || ip == null){
json = JsonUtil.readJson("D:\\js\\js.txt");
JSONObject jsonIp = JSON.parseObject(json);
ip = (String)jsonIp.get("ip");
}else {
JsonUtil.writeJson(path,directoryPath,jsonObject,fileName);
}
pcOperateLog.setIp(ip);
//获取ip地理位置
String address = BaiduMapUtil.getAddress(ip);
// String address = "江苏省南京市";
pcOperateLog.setIpLocation(address);
//调用方法,插入数据库
pcOperateLogMapper.addPcOperateLog(pcOperateLog);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 异常返回通知,用于拦截异常日志信息 连接点抛出异常后执行
*/
@AfterThrowing(pointcut = "operExceptionLogPoinCut()", throwing = "e")
public void saveExceptionLog(JoinPoint joinPoint, Throwable e) {
// 这是我数据库日志表对应的实体类
PcOperateLog pcOperateLog = new PcOperateLog();
try {
// 从切面织入点处通过反射机制获取织入点处的方法
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
// 获取切入点所在的方法
Method method = signature.getMethod();
// 获取请求的类名
String className = joinPoint.getTarget().getClass().getName();
// 获取请求的方法名
String methodName = method.getName();
methodName = className + "." + methodName + "()";
// 获取操作
MyLog myLog = method.getAnnotation(MyLog.class);
if (myLog != null) {
//记录日志的操作内容
pcOperateLog.setRecord(myLog.record());
}
//获取操作者
Map userInfo = GetContext.getContext();
String username = (String)userInfo.get("username");
pcOperateLog.setName(username);
//获取ip地址
String ip = PcLoginLogServiceImpl.ip;
String fileName="js.txt";
String path="D:\\js\\";
String directoryPath = "D:\\js";
JSONObject jsonObject = new JSONObject();
jsonObject.put("ip", ip);
String json = null;
if(ip == "" || ip == null){
json = JsonUtil.readJson("D:\\js\\js.txt");
JSONObject jsonIp = JSON.parseObject(json);
ip = (String)jsonIp.get("ip");
}else {
JsonUtil.writeJson(path,directoryPath,jsonObject,fileName);
}
pcOperateLog.setIp(ip);
String address = BaiduMapUtil.getAddress(ip);
pcOperateLog.setIpLocation(address);
//插入数据库
pcOperateLogMapper.addPcOperateLog(pcOperateLog);
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
5、Mapper类
import com.woniu.pc.entity.PcOperateLog;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface PcOperateLogMapper {
void addPcOperateLog(PcOperateLog pcOperateLog);
List<PcOperateLog> queryAll();
}
6、sql语句
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.woniu.pc.mapper.PcOperateLogMapper">
<insert id="addPcOperateLog">
INSERT INTO t_pc_operate_log(name, time, ip, record, ip_location)
VALUES (#{name}, now(), #{ip}, #{record}, #{ipLocation})
</insert>
<select id="queryAll" resultType="com.woniu.pc.entity.PcOperateLog">
SELECT id, name, time, ip, record, ip_location
FROM t_pc_operate_log
</select>
</mapper>
7、使用注解
在某个controller层的一个的方法上加上注解