Spring AOP實現(xiàn)接口請求記錄到數(shù)據(jù)庫的示例代碼
更新時間:2022年09月26日 14:37:45 作者:AboutChristopher
這篇文章主要介紹了Spring AOP實現(xiàn)接口請求記錄到數(shù)據(jù)庫,代碼包括引入AOP依賴及創(chuàng)建日志記錄表,代碼簡單易懂,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
1.引入AOP依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>2.創(chuàng)建日志記錄表
DROP TABLE IF EXISTS `rule_operate_log`;
CREATE TABLE `rule_operate_log` (
id INT(11) NOT NULL AUTO_INCREMENT COMMENT '日志id',
path VARCHAR(4000) NULL DEFAULT NULL COMMENT '接口地址',
http_method VARCHAR(32) NULL DEFAULT NULL COMMENT '請求方法',
status_code VARCHAR(32) NULL DEFAULT NULL COMMENT '請求返回狀態(tài)碼',
create_time_char VARCHAR(32) NULL DEFAULT NULL COMMENT '日志時間',
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '日志時間戳',
ip varchar(200) NULL DEFAULT NULL COMMENT '請求ip',
params mediumtext NULL COMMENT '請求參數(shù)',
result mediumtext NULL COMMENT '返回值',
exception mediumtext NULL COMMENT '接口異常',
user_id VARCHAR(32) NULL DEFAULT NULL COMMENT '操作用戶',
user_account VARCHAR(32) NULL DEFAULT NULL COMMENT '操作用戶賬號',
user_name VARCHAR(200) NULL DEFAULT NULL COMMENT '操作用戶名稱',
user_org_id VARCHAR(32) NULL DEFAULT NULL COMMENT '操作用戶機構id',
user_org_name VARCHAR(200) NULL DEFAULT NULL COMMENT '操作用戶機構名稱',
operate_name VARCHAR(200) NULL DEFAULT NULL COMMENT '操作名稱',
operate_position VARCHAR(200) NULL DEFAULT NULL COMMENT '操作位置',
log_type VARCHAR(32) NULL DEFAULT NULL COMMENT '日志類型 error:錯誤日志 operate:操作日志',
category_id VARCHAR(32) NULL DEFAULT NULL COMMENT '分類機構id',
cost INT(11) NULL DEFAULT NULL COMMENT '接口耗時',
PRIMARY KEY (id)
) COMMENT = '操作日志表';3.日志實體類
import java.util.Date;
public class RuleOperateLog {
/**
* id
*/
private Integer id;
/**
* 接口地址
*/
private String path;
/**
* 請求方法
*/
private String httpMethod;
/**
* 請求返回狀態(tài)碼
*/
private String statusCode;
/**
* 日志時間
*/
private String createTimeChar;
/**
* 日志時間戳
*/
private Date createTime;
/**
* 請求ip
*/
private String ip;
/**
* 請求參數(shù)
*/
private String params;
/**
* 返回值
*/
private String result;
/**
* 接口異常
*/
private String exception;
/**
* 操作用戶
*/
private String userId;
/**
* 操作用戶賬號
*/
private String userAccount;
/**
* 操作用戶名稱
*/
private String userName;
/**
* 操作用戶機構
*/
private String userOrgId;
/**
* 操作用戶機構名稱
*/
private String userOrgName;
/**
* 操作名稱
*/
private String operateName;
/**
* 操作位置
*/
private String operatePosition;
/**
* 日志類型
*/
private String logType;
/**
* 分類機構id
*/
private String categoryId;
/**
* 請求耗時
*/
private Integer cost;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getHttpMethod() {
return httpMethod;
}
public void setHttpMethod(String httpMethod) {
this.httpMethod = httpMethod;
}
public String getStatusCode() {
return statusCode;
}
public void setStatusCode(String statusCode) {
this.statusCode = statusCode;
}
public String getCreateTimeChar() {
return createTimeChar;
}
public void setCreateTimeChar(String createTimeChar) {
this.createTimeChar = createTimeChar;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getParams() {
return params;
}
public void setParams(String params) {
this.params = params;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public String getException() {
return exception;
}
public void setException(String exception) {
this.exception = exception;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserAccount() {
return userAccount;
}
public void setUserAccount(String userAccount) {
this.userAccount = userAccount;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserOrgId() {
return userOrgId;
}
public void setUserOrgId(String userOrgId) {
this.userOrgId = userOrgId;
}
public String getUserOrgName() {
return userOrgName;
}
public void setUserOrgName(String userOrgName) {
this.userOrgName = userOrgName;
}
public String getOperateName() {
return operateName;
}
public void setOperateName(String operateName) {
this.operateName = operateName;
}
public String getOperatePosition() {
return operatePosition;
}
public void setOperatePosition(String operatePosition) {
this.operatePosition = operatePosition;
}
public String getLogType() {
return logType;
}
public void setLogType(String logType) {
this.logType = logType;
}
public String getCategoryId() {
return categoryId;
}
public void setCategoryId(String categoryId) {
this.categoryId = categoryId;
}
public Integer getCost() {
return cost;
}
public void setCost(Integer cost) {
this.cost = cost;
}
}4.Dao+Mapper+service
import com.xxx.xxx.xxx.entity.RuleOperateLog;
/**
* 操作日志(RuleOperateLog)表數(shù)據(jù)庫訪問層
*
* @author hx
* @since 2022-08-23
*/
public interface RuleOperateLogDao {
/**
* 新增數(shù)據(jù)
*
* @param operateLog
* @return
*/
int insert(RuleOperateLog operateLog);
}<?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.xxx.xxx.xxx.dao.RuleOperateLogDao">
<resultMap type="com.xxx.xxx.xxx.entity.RuleOperateLog" id="RuleOperateLogMap">
<result property="id" column="id" jdbcType="INTEGER"/>
<result property="path" column="path" jdbcType="VARCHAR"/>
<result property="httpMethod" column="http_method" jdbcType="VARCHAR"/>
<result property="statusCode" column="status_code" jdbcType="VARCHAR"/>
<result property="createTimeChar" column="create_time_char" jdbcType="VARCHAR"/>
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
<result property="ip" column="ip" jdbcType="VARCHAR"/>
<result property="params" column="params" jdbcType="VARCHAR"/>
<result property="result" column="result" jdbcType="VARCHAR"/>
<result property="exception" column="exception" jdbcType="VARCHAR"/>
<result property="userId" column="user_id" jdbcType="VARCHAR"/>
<result property="userAccount" column="user_account" jdbcType="VARCHAR"/>
<result property="userName" column="user_name" jdbcType="VARCHAR"/>
<result property="userOrgId" column="user_org_id" jdbcType="VARCHAR"/>
<result property="userOrgName" column="user_org_name" jdbcType="VARCHAR"/>
<result property="operateName" column="operate_name" jdbcType="VARCHAR"/>
<result property="operatePosition" column="operate_position" jdbcType="VARCHAR"/>
<result property="logType" column="log_type" jdbcType="VARCHAR"/>
<result property="categoryId" column="category_id" jdbcType="VARCHAR"/>
<result property="cost" column="cost" jdbcType="INTEGER"/>
</resultMap>
<insert id="insert" keyProperty="id" useGeneratedKeys="true">
insert into rule_operate_log (id, path, http_method, status_code, create_time_char, create_time,
ip, params, result, exception, user_id, user_account, user_name, user_org_id,
user_org_name, operate_name, operate_position, log_type, category_id, cost)
values (#{id}, #{path}, #{httpMethod}, #{statusCode}, #{createTimeChar}, #{createTime}, #{ip}, #{params}, #{result},
#{exception},#{userId}, #{userAccount}, #{userName}, #{userOrgId}, #{userOrgName}, #{operateName}, #{operatePosition},
#{logType}, #{categoryId}, #{cost})
</insert>
</mapper>import com.xxx.xxx.xxx.entity.RuleOperateLog;
/**
* 操作日志(RuleOperateLog)表服務接口
*
* @author hx
* @since 2022-08-23
*/
public interface RuleOperateLogService {
/**
* 保存日志
*
* @param ruleOperateLog
* @return
*/
void saveLog(RuleOperateLog ruleOperateLog);
}import com.xxx.xxx.xxx.dao.RuleOperateLogDao;
import com.xxx.xxx.xxx.entity.RuleOperateLog;
import com.xxx.xxx.xxx.service.RuleOperateLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 操作日志(RuleOperateLog)表服務實現(xiàn)類
*
* @author hx
* @since 2022-08-23
*/
@Service("RuleOperateLogService")
public class RuleOperateLogServiceImpl implements RuleOperateLogService {
@Autowired
private RuleOperateLogDao operateLogDao;
@Override
public void saveLog(RuleOperateLog ruleOperateLog) {
operateLogDao.insert(ruleOperateLog);
}
}5.自定義注解
import java.lang.annotation.*;
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface LogResource {
/**
* 服務名稱
* @return
*/
String name();
/**
* 操作位置描述
* @return
*/
String position() default "";
/**
* 日志類型
* @return
*/
String logType() default "";
}6.操作日志切面類
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.com.xxx.xxx.xxx.annotation.LogResource;
import com.com.xxx.xxx.xxx.constants.LogTypeConstants;
import com.com.xxx.xxx.xxx.entity.RuleOperateLog;
import com.com.xxx.xxx.xxx.service.RuleOperateLogService;
import org.aspectj.lang.ProceedingJoinPoint;
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.http.HttpHeaders;
import org.springframework.scheduling.annotation.Async;
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 javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 操作日志切面類
*
* @author hx
* @since 2022-08-23
*/
@Aspect
@Component
public class OperateLogAspect {
@Autowired
private RuleOperateLogService operateLogService;
//掃描使用@LogResource注解的方法
@Pointcut("@annotation(com.com.xxx.xxx.xxx.annotation.LogResource)")
public void logPointCut() { };
@Around("logPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
Date startTime = new Date();
String exception = null;
String result = null;
try {
Object obj = point.proceed();
if (obj != null) {
result = JSONObject.toJSONString(obj);
}
return obj;
} catch (Exception e) {
//請求時報錯
exception = e.toString();
throw e;
} finally {
//操作和報錯日志都記錄
HttpServletResponse response
= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
int statusCode = response.getStatus();
if (exception != null) {
/** CHECKSTYLE:OFF:MagicNumber */
statusCode = 500;
/** CHECKSTYLE:ON:MagicNumber */
}
syncSaveLog(point, startTime, new Date(), exception, result, statusCode);
}
}
@Async
void syncSaveLog(ProceedingJoinPoint joinPoint, Date startTime, Date endTime,
String exception, String result, int statusCode) {
RuleOperateLog log = new RuleOperateLog();
try {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
LogResource annotation = method.getAnnotation(LogResource.class);
if (annotation != null) {
//注解上的描述
log.setOperateName(annotation.name());
}
Date nowDate = new Date();
log.setCreateTimeChar(new SimpleDateFormat("yyyyMMddhhmmss").format(nowDate));
log.setCreateTime(nowDate);
//入?yún)?
if (joinPoint.getArgs() != null) {
try {
log.setParams(JSONObject.toJSONString(joinPoint.getArgs(),
SerializerFeature.IgnoreNonFieldGetter));
} catch (Exception e) {
e.printStackTrace();
}
}
Long cost = endTime.getTime() - startTime.getTime();
log.setCost(cost.intValue());
HttpServletRequest request
= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
if (request != null) {
log.setUserName(request.getHeader(HttpHeaders.USER_AGENT));
log.setPath(request.getRequestURI());
log.setHttpMethod(request.getMethod());
log.setIp(request.getRemoteAddr());
}
log.setStatusCode(String.valueOf(statusCode));
log.setResult(result);
/** CHECKSTYLE:OFF:MagicNumber */
if (statusCode > 400 && exception != null) {
log.setException(exception);
log.setLogType(LogTypeConstants.ERROR);
} else {
log.setLogType(LogTypeConstants.OPERATE);
}
/** CHECKSTYLE:ON:MagicNumber */
operateLogService.saveLog(log);
} catch (Exception e) {
e.printStackTrace();
}
/* //啟動一個線程,執(zhí)行報錯日志防止影響主請求
new Thread() {
@Override
public void run() {
try {
//保存到數(shù)據(jù)庫
operLogMapper.insertOper(operLog);
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();*/
}
}7.使用

到此這篇關于Spring AOP實現(xiàn)接口請求記錄到數(shù)據(jù)庫的文章就介紹到這了,更多相關Spring AOP接口請求記錄數(shù)據(jù)庫內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
springboot結合mybatis-plus基于session模擬短信注冊功能
本文主要介紹了springboot結合mybatis-plus基于session模擬短信注冊功能,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-11-11
Java使用jxl包寫Excel文件適合列寬實現(xiàn)
用jxl.jar包,讀寫過Excel文件。也沒有注意最適合列寬的問題,但是jxl.jar沒有提供最適合列寬的功能,上次用到寫了一下,可以基本實現(xiàn)最適合列寬。2013-11-11
解決在Idea 2020.2下使用 Lombok的注解不生效的問題(插件安裝了,依賴也寫了,自動注解也設置了)
這篇文章主要介紹了在Idea 2020.2下使用 Lombok的注解不生效的問題(插件安裝了,依賴也寫了,自動注解也設置了),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-08-08
Java通用BouncyCastle實現(xiàn)的DES3加密的方法
這篇文章主要介紹了Java通用BouncyCastle實現(xiàn)的DES3加密的方法,本文給大家介紹的非常詳細,對大家的學習或工作,具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12

