目录
- <dependency>
- <groupId>org.aspectjgroupId>
- <artifactId>aspectjweaverartifactId>
- dependency>
- <dependency>
- <groupId>org.springframework.bootgroupId>
- <artifactId>spring-boot-starter-aopartifactId>
- <scope>testscope>
- dependency>
- <dependencies>
- <dependency>
- <groupId>org.projectlombokgroupId>
- <artifactId>lombokartifactId>
- dependency>
- dependencies>
切面方法说明如下:
| @Aspect | 作用是把当前类标识为一个切面供容器读取 |
| @Pointcut | (切入点):就是带有通知的连接点,在程序中主要体现为书写切入点表达式 |
| @Before | 标识一个前置增强方法,相当于BeforeAdvice的功能 |
| @AfterReturning | 后置增强,相当于AfterReturningAdvice,方法退出时执行 |
| @AfterThrowing | 异常抛出增强,相当于ThrowsAdvice |
| @After | final增强,不管是抛出异常或者正常退出都会执行 |
| @Around | 环绕增强,相当于MethodInterceptor |
- package com.shucha.deveiface.biz.aspect;
-
- import java.lang.annotation.*;
-
- /**
- * @author tqf
- * @Description 自定义拦截日志
- * @Version 1.0
- * @since 2022-08-08 15:28
- */
- @Target({ElementType.PARAMETER, ElementType.METHOD})
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- public @interface Log {
-
- /**
- * 操作描述 查询、新增、修改、删除等
- * @return
- */
- String menu() default "";
-
- /**
- * 接口名称 不需要填写 可以通过request.getRequestURL().toString(); 获取
- * @return
- */
- String operation() default "";
-
- /**
- * 是否记录请求参数数据, 默认true: 记录; false:不记录
- *
- * @return
- */
- boolean isData() default true;
- }
- package com.shucha.deveiface.biz.aspect;
-
-
-
- import com.alibaba.fastjson.JSON;
- import com.alibaba.fastjson.serializer.SerializerFeature;
- import com.sdy.common.model.Response;
- import com.sdy.mvc.controller.BaseController;
- import com.sdy.mvc.utils.HttpUtil;
- import com.shucha.deveiface.biz.model.SysLog;
- import com.shucha.deveiface.biz.service.SysLogService;
- import feign.Request;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.commons.lang3.ArrayUtils;
- import org.aspectj.lang.JoinPoint;
- import org.aspectj.lang.ProceedingJoinPoint;
- import org.aspectj.lang.Signature;
- 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.RequestContextHolder;
- import org.springframework.web.context.request.ServletRequestAttributes;
-
- import javax.servlet.http.HttpServletRequest;
- import java.lang.reflect.Method;
- import java.lang.reflect.Parameter;
- import java.util.Date;
- import java.util.Enumeration;
- import java.util.HashMap;
- import java.util.Map;
-
- /**
- * @author tqf
- * @Description 日志切面类
- * @Version 1.0
- * @since 2022-08-08 15:28
- */
- @Aspect
- @Component
- @Slf4j
- @Order(1)
- public class LogAspect {
-
- @Autowired
- private SysLogService sysLogService;
-
- private final ThreadLocal
startTime = new ThreadLocal<>(); -
- // 配置织入点
- @Pointcut("@annotation(Log)")
- public void logPointCut() {
- }
-
- @Before("logPointCut()")
- private void before() {
- startTime.set( System.currentTimeMillis());
- }
-
- /**
- * 处理完请求后执行
- * @param joinPoint
- * @param res
- * @throws Exception
- */
- @AfterReturning(returning = "res", pointcut = "logPointCut()")
- public void afterReturning(JoinPoint joinPoint, Response res) throws Exception {
- long nowTime = System.currentTimeMillis();
- HttpServletRequest request = getRequest();
- handleLog(joinPoint, null, res, nowTime, request);
- }
-
- /**
- * 拦截异常操作
- * @param joinPoint 切点
- * @param e 异常
- */
- @AfterThrowing(value = "logPointCut()", throwing = "e")
- public void doAfterThrowing(JoinPoint joinPoint, Exception e) throws Exception {
- // 从上下文中获取reqeust
- ServletRequestAttributes servletRequestAttributes =
- (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
- // HttpServletRequest request = getRequest();
- HttpServletRequest request = servletRequestAttributes.getRequest();
-
- handleLog(joinPoint, e, null, System.currentTimeMillis(), request);
- }
-
- protected void handleLog(final JoinPoint joinPoint, final Exception e, Response jsonResult, Long nowTime, HttpServletRequest request) throws Exception {
- Log controllerLog = getAnnotationLog(joinPoint);
- ProceedingJoinPoint point = (ProceedingJoinPoint)joinPoint;
- if (controllerLog == null) {
- return;
- }
- // 数据库日志
- SysLog sysLog = new SysLog();
- // 接口地址
- String requestUrl = request.getRequestURL().toString();
- // 请求的IP地址
- String ip = HttpUtil.getIpAddr(request);
- sysLog.setIp(ip);
- // 获取操作内容
- String content = controllerLog.menu();
-
- // 获取请求参数
- String requestData = "";
- if(controllerLog.isData()){
- requestData = getRequestParams(point, request);
- }
- if (jsonResult == null) {
- content = content + "--出现服务异常!";
- }
- if (jsonResult != null && !jsonResult.getSuccess()) {
- content = content + "--执行失败!";
- }
- sysLog.setContent(content)
- .setType(content)
- .setCreateTime(new Date())
- .setRequestUrl(requestUrl)
- .setRequestData(requestData);
- // 保存数据库
- sysLogService.save(sysLog);
- }
-
- /**
- * 是否存在注解,如果存在就获取
- */
- private Log getAnnotationLog(JoinPoint joinPoint) {
- Signature signature = joinPoint.getSignature();
- MethodSignature methodSignature = (MethodSignature) signature;
- Method method = methodSignature.getMethod();
- if (method != null) {
- return method.getAnnotation(Log.class);
- }
- return null;
- }
-
- private HttpServletRequest getRequest() {
- ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
- return attributes.getRequest();
- }
-
- /**
- * 获取请求参数 json格式返回
- * @param request
- * @return
- */
- private String getParameterName(HttpServletRequest request){
- // 增加查询日志 获取所有查询的参数名称和值 json格式存储
- Map map = new HashMap();
- Enumeration paramNames = request.getParameterNames();
- while (paramNames.hasMoreElements()) {
- String paramName = (String) paramNames.nextElement();
- String[] paramValues = request.getParameterValues(paramName);
- if (paramValues.length == 1) {
- String paramValue = paramValues[0];
- if (paramValue.length() != 0) {
- map.put(paramName, paramValue);
- }
- }
- }
- return JSON.toJSONString(map);
- }
-
- /**
- * 获取请求参数
- * @param request
- * @return
- */
- public String getRequestParams(ProceedingJoinPoint point, HttpServletRequest request) {
- MethodSignature methodSignature = (MethodSignature)point.getSignature();
- Method method = methodSignature.getMethod();
- String queryString = null;
- String requestMethod = request.getMethod();
- if (requestMethod.equals(Request.HttpMethod.POST.name())) {
- //参数值
- Object[] args = ArrayUtils.toArray(point.getArgs());
- queryString = JSON.toJSONString(args[0], SerializerFeature.WriteMapNullValue);
- }
- else {
- //参数名
- Parameter[] parameters = method.getParameters();
- //参数值
- Object[] args = ArrayUtils.toArray(point.getArgs());
- Map
map = new HashMap<>(); - for (int i = 0; i < parameters.length; i++) {
- map.put(parameters[i].getName(), args[i]);
- }
- queryString = JSON.toJSONString(map);
- }
- return queryString;
- }
-
- }
- package com.shucha.deveiface.biz.model;
-
- import com.baomidou.mybatisplus.annotation.TableId;
- import com.fasterxml.jackson.annotation.JsonFormat;
- import com.sdy.common.model.BaseModel;
- import com.sdy.common.utils.DateUtil;
- import io.swagger.annotations.ApiModelProperty;
- import lombok.Data;
- import lombok.EqualsAndHashCode;
- import lombok.experimental.Accessors;
-
- import java.util.Date;
-
- /**
- *
- * 用户操作日志
- *
- *
- * @author tqf
- * @since 2022-08-08 15:25
- */
- @Data
- @EqualsAndHashCode(callSuper = true)
- @Accessors(chain = true)
- public class SysLog extends BaseModel {
- private static final long serialVersionUID = 1L;
-
- /**
- * 主键
- */
- @ApiModelProperty(value = "主键")
- @TableId
- private Long id;
-
- /**
- * 操作用户id
- */
- @ApiModelProperty(value = "操作用户id")
- private Long userId;
-
- @ApiModelProperty(value = "请求参数")
- private String requestData;
-
- @ApiModelProperty(value = "请求接口地址")
- private String requestUrl;
-
- /**
- * IP地址
- */
- @ApiModelProperty(value = "IP地址")
- private String ip;
-
- /**
- * 操作内容
- */
- @ApiModelProperty(value = "操作内容")
- private String content;
-
- /**
- * 操作类型
- */
- @ApiModelProperty(value = "操作类型")
- private String type;
-
- /**
- * 创建时间
- */
- @ApiModelProperty(value = "创建时间")
- @JsonFormat(pattern = DateUtil.DATETIME_FORMAT)
- private Date createTime;
-
- }
创建表和插入数据
- SET NAMES utf8mb4;
- SET FOREIGN_KEY_CHECKS = 0;
-
- -- ----------------------------
- -- Table structure for sys_log
- -- ----------------------------
- DROP TABLE IF EXISTS `sys_log`;
- CREATE TABLE `sys_log` (
- `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
- `user_id` int(11) NULL DEFAULT NULL COMMENT '操作用户id',
- `ip` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT 'IP地址',
- `content` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '操作内容',
- `request_url` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '请求接口地址',
- `request_data` longtext CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL COMMENT '请求参数',
- `type` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '操作类型\r\n0:登陆\r\n1:新增用户\r\n2:开户\r\n3:用户基本信息编辑\r\n4:用户资源编辑\r\n5:新增角色\r\n6编辑角色\r\n7:角色权限编辑\r\n8:角色关联用户编辑\r\n9:新增菜单\r\n10:菜单编辑\r\n11:日志查询',
- `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
- PRIMARY KEY (`id`) USING BTREE,
- INDEX `idx_user_id`(`user_id`) USING BTREE
- ) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_unicode_ci COMMENT = '操作日志信息' ROW_FORMAT = Dynamic;
-
- -- ----------------------------
- -- Records of sys_log
- -- ----------------------------
- INSERT INTO `sys_log` VALUES (1, NULL, '192.168.0.111', '查询数据', 'http://192.168.0.111:50041/test/getData', '{}', '查询数据', '2022-08-08 17:21:51');
- INSERT INTO `sys_log` VALUES (2, NULL, '192.168.0.111', '新增数据发发发', NULL, NULL, NULL, NULL);
- INSERT INTO `sys_log` VALUES (3, NULL, '192.168.0.111', '新增数据', 'http://192.168.0.111:50041/test/saveData', '{\"content\":\"新增数据发发发\",\"createTime\":null,\"id\":2,\"ip\":\"192.168.0.111\",\"requestData\":null,\"requestUrl\":null,\"type\":null,\"userId\":null}', '新增数据', '2022-08-08 17:22:12');
-
- SET FOREIGN_KEY_CHECKS = 1;
- package com.shucha.deveiface.biz.service;
-
- import com.sdy.mvc.service.BaseService;
- import com.shucha.deveiface.biz.model.SysLog;
-
- /**
- *
- * 用户操作日志 服务类
- *
- *
- * @author cgj
- * @since 2021-07-13
- */
- public interface SysLogService extends BaseService
{ -
- }
- package com.shucha.deveiface.biz.service.impl;
-
- import com.sdy.mvc.service.impl.BaseServiceImpl;
- import com.shucha.deveiface.biz.mapper.SysLogMapper;
- import com.shucha.deveiface.biz.model.SysLog;
- import com.shucha.deveiface.biz.service.SysLogService;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
-
- /**
- *
- * 用户操作日志 服务实现类
- *
- *
- * @author cgj
- * @since 2021-07-13
- */
- @Slf4j
- @Service
- public class SysLogServiceImpl extends BaseServiceImpl
implements SysLogService { - @Autowired
- private SysLogMapper sysLogMapper;
- }
- package com.shucha.deveiface.web.controller;
-
- import com.sdy.common.model.Response;
- import com.shucha.deveiface.biz.aspect.Log;
- import com.shucha.deveiface.biz.model.SysLog;
- import com.shucha.deveiface.biz.service.SysLogService;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.*;
-
- /**
- * @author tqf
- * @Description
- * @Version 1.0
- * @since 2022-08-08 15:23
- */
- @RestController
- @RequestMapping("/test")
- public class TestController {
-
- @Autowired
- private SysLogService logService;
-
- @Log(menu = "查询数据")
- @GetMapping("/getData")
- public Response test(){
- return Response.success("请求成功");
- }
-
- @Log(menu = "新增数据")
- @PostMapping("/saveData")
- public Response saveData(@RequestBody SysLog sysLog){
- logService.save(sysLog);
- return Response.success();
- }
- }