第一步: 创建日志表
第二步: 添加aop依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
第三步: 自定义日志注解及代码实现
自定义一个名为LogAnno的注解
package com.minapp.admin.annotation;
import java.lang.annotation.*;
/**
* @Description: 日志注解
* @Param:
* @return:
* @Author: XQD
* @Date:2021/3/9 10:33
*/
@Target(ElementType.METHOD) //注解放置的目标位置,METHOD是可注解在方法级别上
@Retention(RetentionPolicy.RUNTIME) // 注解在哪个阶段执行 运行时可见
public @interface LogAnno {
// 记录日志的操作类型
String operateType();
}
使用aop实现日志,数据表中有自己的业务字段,自行更改
package com.minapp.admin.aop;
import com.alibaba.fastjson.JSON;
import com.minapp.admin.annotation.LogAnno;
import com.minapp.admin.controller.BaseController;
import com.minapp.admin.entity.TdAdminOperLog;
import com.minapp.admin.mapper.TdAdminOperLogMapper;
import com.minapp.admin.utils.HttpContextUtil;
import com.minapp.admin.utils.HttpMethod;
import com.minapp.admin.utils.ServletUtils;
import org.apache.commons.lang3.StringUtils;
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.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
/**
* @ClassName: LogAopAspect
* @Description: AOP实现日志 aop环绕通知类
* @Authror: XQD
* @Date: 2021/3/9 10:36
*/
@Order(3) // 标记支持AspectJ的切面排序
@Component
@Aspect
public class LogAopAspect extends BaseController {
@Autowired
private TdAdminOperLogMapper operLogMapper;
@Pointcut("@annotation(com.minapp.admin.annotation.LogAnno)")
public void operLogPoinCut() {
}
@AfterReturning(value = "operLogPoinCut()", returning = "keys")
public Object aroundAdvice(JoinPoint joinPoint, Object keys) {
// 1.方法执行前的处理,相当于前置通知
// 获取方法签名
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
// 获取方法
Method method = methodSignature.getMethod();
// 获取方法上面的注解
LogAnno logAnno = method.getAnnotation(LogAnno.class);
// 获取操作描述的属性值
String operateType = logAnno.operateType();
TdAdminOperLog adminOperLog = new TdAdminOperLog();
String token = getToken();
String[] tokenArray = token.split("-");
String loginId = tokenArray[1];
adminOperLog.setOperateor(loginId);
adminOperLog.setOperateProjectId(projectId(token));
String className = joinPoint.getTarget().getClass().getName();
String signatureName = methodSignature.getName();
adminOperLog.setOperateMethod(className + "." + signatureName + "()");
String requestMethod = ServletUtils.getRequest().getMethod();
if ("PUT".equals(requestMethod) || "POST".equals(requestMethod)) {
String params = argsArrayToString(joinPoint.getArgs());
adminOperLog.setParams(StringUtils.substring(params, 0, 2000));
} else {
// 获取RequestAttributes
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
// 从获取RequestAttributes中获取HttpServletRequest的信息
HttpServletRequest request = (HttpServletRequest) requestAttributes
.resolveReference(RequestAttributes.REFERENCE_REQUEST);
// 请求的参数
Map<String, String> rtnMap = converMap(request.getParameterMap());
adminOperLog.setParams(StringUtils.substring(JSON.toJSONString(rtnMap), 0, 2000));
}
// 接口返回值参数
adminOperLog.setOperateResult(JSON.toJSONString(keys));
adminOperLog.setOperateType(operateType);
String ip = HttpContextUtil.getIpAddress();
adminOperLog.setOperateIp(ip);
Object result = null;
operLogMapper.insert(adminOperLog);// 添加日志记录
return result;
}
/**
* 转换request 请求参数
*
* @param paramMap request获取的参数数组
*/
public Map<String, String> converMap(Map<String, String[]> paramMap) {
Map<String, String> rtnMap = new HashMap<String, String>();
for (String key : paramMap.keySet()) {
rtnMap.put(key, paramMap.get(key)[0]);
}
return rtnMap;
}
/**
* 参数拼装
*/
private String argsArrayToString(Object[] paramsArray) {
String params = "";
if (paramsArray != null && paramsArray.length > 0) {
for (int i = 0; i < paramsArray.length; i++) {
if (!isFilterObject(paramsArray[i])) {
Object jsonObj = JSON.toJSON(paramsArray[i]);
if (jsonObj != null) {
params += jsonObj.toString() + " ";
}
}
}
}
return params.trim();
}
/**
* 判断是否需要过滤的对象。
*
* @param o 对象信息。
* @return 如果是需要过滤的对象,则返回true;否则返回false。
*/
public boolean isFilterObject(final Object o) {
return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse;
}
}
获取ip工具类
package com.minapp.admin.utils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
* @ClassName: HttpContextUtil
* @Description: TODO
* @Authror: XQD
* @Date: 2021/3/9 11:07
*/
public class HttpContextUtil {
public static HttpServletRequest getRequest() {
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
.getRequest();
}
/**
* @Description: 获取IP地址的方法
* @Param: []
* @return: java.lang.String
* @Author: XQD
* @Date:2021/3/9 11:22
*/
public static String getIpAddress() {
HttpServletRequest request = getRequest();
String 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.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
}
客户端工具类
package com.minapp.admin.utils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* 客户端工具类
*
* @author ruoyi
*/
public class ServletUtils
{
/**
* 获取String参数
*/
public static String getParameter(String name)
{
return getRequest().getParameter(name);
}
/**
* 获取request
*/
public static HttpServletRequest getRequest()
{
return getRequestAttributes().getRequest();
}
/**
* 获取response
*/
public static HttpServletResponse getResponse()
{
return getRequestAttributes().getResponse();
}
/**
* 获取session
*/
public static HttpSession getSession()
{
return getRequest().getSession();
}
public static ServletRequestAttributes getRequestAttributes()
{
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
return (ServletRequestAttributes) attributes;
}
/**
* 将字符串渲染到客户端
*
* @param response 渲染对象
* @param string 待渲染的字符串
* @return null
*/
public static String renderString(HttpServletResponse response, String string)
{
try
{
response.setStatus(200);
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
response.getWriter().print(string);
}
catch (IOException e)
{
e.printStackTrace();
}
return null;
}
}
实现方式
数据库记录