利用Aop实现,此处使用的是前置通知。
1.获取真实ip地址工具类
package com.kttsoft.tjrhdv.web.log;
/**
* @className: IpUtiles
* @description: TODO 类描述
* @author: ShiSan
* @date: 2022/3/16
**/
import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class IpUtiles {
/**
* 获取真实IP
* @param request 请求体
* @return 真实IP
*/
public static String getRealIp(HttpServletRequest request) {
// 这个一般是Nginx反向代理设置的参数
String ip = request.getHeader("X-Real-IP");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Forwarded-For");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
String comma = ",";
String localhost = "127.0.0.1";
if (ip.contains(comma)) {
ip = ip.split(",")[0];
}
if (localhost.equals(ip)) {
// 获取本机真正的ip地址
try {
ip = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
return ip;
}
}
2.实体类
package com.kttsoft.tjrhdv.web.log;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
/**
* @className: LogTest
* @description: log测试
* @author: ShiSan
* @date: 2022/3/18
**/
@Data
@TableName("LOG_TEST")
public class LogTest implements Serializable {
@TableField("NAME")
private String name;
@TableField("IP")
private String ip;
//请求接口
@TableField("CONNECTOR")
private String connector;
@TableField("METHOD")
private String method;
@TableField("PARAMS")
private String params;
@TableField("BROWSERNAME")
private String browserName;
@TableField("TIME")
private String time;
}
3.Mapper层
package com.kttsoft.tjrhdv.web.log;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
/**
* @className: LogTestMapper
* @description: 记录用户操作记录
* @author: ShiSan
* @date: 2022/3/18
**/
@Repository
public interface LogTestMapper extends BaseMapper<LogTest> {
}
4.操作记录对象方法(重点是这里)
以下展示向数据库存储的数据为我个人所需,可自行定义。
package com.kttsoft.tjrhdv.web.log;
import com.kttsoft.tjrhdv.config.common.JwtUtil;
import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.UserAgent;
import io.jsonwebtoken.Claims;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Objects;
@Aspect
@Component
@EnableAspectJAutoProxy
public class SystemLogAspect {
@Autowired
LogTestMapper logTestMapper;
//本地异常日志记录对象
private static final Logger logger = LoggerFactory.getLogger(SystemLogAspect.class);
//Controller层切点(切点自定义,语法不会自行百度)
@Pointcut("within(com.kttsoft.tjrhdv.web.modules.rest..*)")
public void controllerAspect() {
}
/**
* @author ShiSan
* @description 记录用户操作日志
**/
@Before("controllerAspect()")
public void doBefore(JoinPoint joinPoint) {
HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
//获取ip
String ip = IpUtiles.getRealIp(request);
//通过token获取用户
String token = request.getHeader("token");
//用户未登录直接访问接口
Object name = null;
Object dwbm = null;
//防止空指针
if(StringUtils.isNotBlank(token)&&!token.equals("null")) {
Claims claims = JwtUtil.parseJWT(token);
if (claims != null) {
name = claims.get("username");
}
}
try {
//此处为自定义的实体类对象
LogTest logTest = new LogTest();
logTest.setName((String) name);
logTest.setDwbm((String) dwbm);
logTest.setIp(ip);
//获取接口
logTest.setConnector(request.getRequestURI());
//获取方法
logTest.setMethod(joinPoint.getSignature().getName());
//获取参数
if (Arrays.toString(joinPoint.getArgs()).length() < 2000) {
logTest.setParams(Arrays.toString(joinPoint.getArgs()));
} else {
logTest.setParams("参数超出记录限制");
}
logTest.setTime(df.format(new Date()));
String ua = request.getHeader("User-Agent");
//转成UserAgent对象
UserAgent userAgent = UserAgent.parseUserAgentString(ua);
//获取浏览器信息
Browser browser = userAgent.getBrowser();
String browserName = browser.getName();
logTest.setBrowserName(browserName);
logTestMapper.insert(logTest);
} catch (Exception e) {
//记录本地异常日志
logger.error(">>>>>用户操作日志异常信息:{}", e.getMessage());
}
}
}