目录结构
代码
package com.demo.mymaintest.constants;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 系统日志注解
*
* @author Mark sunlightcs@gmail.com
*/
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target({ElementType.METHOD,ElementType.PARAMETER })
public @interface SysLog {
String value() default "";
}
package com.demo.mymaintest.aop;
import com.alibaba.fastjson.JSONObject;
import com.demo.mymaintest.constants.SysLog;
import com.demo.mymaintest.entity.SysLogEntity;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
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.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
/**
* 系统日志,切面处理类
*
* @author yhj
*/
@Aspect
@Component
public class SysLogAspect {
// 定义切点 切点表达式指向SysLog注解,我们再业务方法上可以加上SysLog注解,然后所标注
// 的方法都能进行日志记录
@Pointcut("@annotation(com.demo.mymaintest.constants.SysLog)")
public void logPointCut() {}
@Around(value = "logPointCut()")
private Object Around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String requestURI = request.getRequestURI();
String requestMethod = request.getMethod();
String remoteAddr = request.getRemoteAddr();
SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Long nowDate = System.currentTimeMillis(); // 步入时间戳
String startTime = dateformat.format(nowDate);
MethodSignature method1 = (MethodSignature) proceedingJoinPoint.getSignature();
Class<?> currentClass = proceedingJoinPoint.getTarget().getClass();
Object proceed = proceedingJoinPoint.proceed();
List<Object> allArgs = Arrays.asList(proceedingJoinPoint.getArgs());
List<Object> args =
allArgs.stream()
.map(
arg -> {
if (!(arg instanceof HttpServletRequest)
&& !(arg instanceof HttpServletResponse)) {
return arg;
} else {
return null;
}
})
.filter(arg -> arg != null)
.collect(Collectors.toList());
SysLogEntity sysLogEntity = new SysLogEntity();
sysLogEntity.setUsername("登录人从request中获取");
MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
Method method = signature.getMethod();
SysLog syslog = method.getAnnotation(SysLog.class);
if(syslog != null){
//注解上的描述
sysLogEntity.setOperation(syslog.value());
}
sysLogEntity.setRequestPath(requestURI);
sysLogEntity.setRequestMethod(requestMethod);
sysLogEntity.setCurrentTimeMills(startTime);
sysLogEntity.setArgsType(getMethodArgumentTypeName(method1));
sysLogEntity.setAllArgs(args);
sysLogEntity.setResponseData(proceed != null ? proceed.toString() : "null");
sysLogEntity.setExecuteTimeMills((System.currentTimeMillis() - nowDate) + "ms");
sysLogEntity.setClassMethodLocation(currentClass.getName() + "." + method.getName());
sysLogEntity.setRemoteAddr(remoteAddr);
sysLogEntity.setNowTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
sysLogEntity.setResponseType(method.getReturnType().getName());
// TODO 将sysLogEntity存入ES
System.out.println(JSONObject.toJSONString(sysLogEntity));
return proceed;
}
@AfterThrowing(value = "logPointCut()")
private void AfterThrowing() {
System.out.println("异常通知");
}
private Map<String, String> getMethodArgumentTypeName(MethodSignature method) {
Map<String, String> map = new HashMap<>();
String[] argTypeNames = method.getParameterNames();
Class[] parameterTypes = method.getParameterTypes();
for (int i = 0; i < parameterTypes.length; i++) {
map.put(parameterTypes[i].getName(), argTypeNames[i]);
}
return map;
}
}
package com.demo.mymaintest.controller;
import com.demo.mymaintest.constants.SysLog;
import com.demo.mymaintest.entity.BookEntity;
import com.demo.mymaintest.entity.SysUser;
import com.demo.mymaintest.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
/**
* @ClassName TestApiController
* @Author yhj
* @Date 2023/7/15 13:22
* @Description
* @Version 1.0
*/
@RestController
@RequestMapping("/api")
@Slf4j
public class TestApiController {
@PostMapping("/add")
@SysLog(value = "添加数据测试")
public R test(@RequestBody BookEntity bookEntity) {
bookEntity.setBookImg("testImg");
bookEntity.setBookIntro("书籍简介");
return R.ok(200,"添加成功",bookEntity);
}
@PostMapping("/login")
@SysLog(value = "用户登录")
public ResponseEntity login(@RequestBody SysUser sysUser){
String ok = "恭喜你登录成功";
if(sysUser.getUserName().equals("test")){
return ResponseEntity.ok(ok);
}
return ResponseEntity.ok().body("登录失败");
}
@DeleteMapping("/delete")
@SysLog("删除")
public ResponseEntity<String> deleteById(@PathVariable("id") Integer id){
return ResponseEntity.ok("删除成功");
}
}
package com.demo.mymaintest.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
/**
*
*
* @author yhj
* @date 2023-06-12 09:47:10
*/
@Data
public class BookEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
*
*/
@TableId
private Integer bookId;
/**
* 书籍编号
*/
private String bookIsbn;
/**
* 书籍名称
*/
private String bookName;
/**
* 书籍价格
*/
private Float bookPrice;
/**
* 书籍封面
*/
private String bookImg;
/**
* 简介
*/
private String bookIntro;
/**
* 已购数量
*/
private int bookPurchasedNumber;
}
package com.demo.mymaintest.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 用户表
* </p>
*
* @author jerry
* @since 2021-06-16
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class SysUser implements Serializable {
private static final long serialVersionUID=1L;
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 用户编号
*/
//@ApiModelProperty("用户编号")
private String userCode;
/**
* 用户名
*/
//@ApiModelProperty("用户名")
private String userName;
/**
* 登录密码
*/
//@ApiModelProperty("登录密码")
private String password;
/**
* 真实姓名
*/
//@ApiModelProperty("真实姓名")
private String realName;
/**
* 手机号码
*/
//@ApiModelProperty("手机号码")
private String mobile;
/**
* 邮箱地址
*/
//@ApiModelProperty("邮箱地址")
private String email;
/**
* 组织机构id
*/
//@ApiModelProperty("组织机构id")
private Long orgId;
/**
* 组织机构名称
*/
//@ApiModelProperty("组织机构名称")
private String orgName;
/**
* 用户类型
*/
//@ApiModelProperty("用户类型")
private Integer userType;
/**
* 描述
*/
//@ApiModelProperty("描述")
private String userDesc;
/**
* 联系地址
*/
//@ApiModelProperty("联系地址")
private String address;
/**
* 传真
*/
//@ApiModelProperty("传真")
private String fax;
/**
* 邮编
*/
//@ApiModelProperty("邮编")
private String postalcode;
/**
* 状态(0:禁用 1:正常)
*/
//@ApiModelProperty("状态(0:禁用 1:正常)")
private Integer status;
/**
* 数据权限类型(role user group)
*/
//@ApiModelProperty("数据权限类型(role user group)")
private String permissionType;
/**
* 创建时间
*/
//@ApiModelProperty("创建时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;
/**
* 创建人
*/
//@ApiModelProperty("创建人")
private String createBy;
/**
* 更新时间
*/
//@ApiModelProperty("更新时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date updateTime;
/**
* 更新人
*/
//@ApiModelProperty("更新人")
private String updateBy;
/**
* 是否删除(0-否 1-是)
*/
//@ApiModelProperty("是否删除(0-否 1-是)")
private Integer isDeleted;
/**
* 公司地址
*/
//@ApiModelProperty("公司地址")
private String orgAddress;
/**
* 部门id
*/
//@ApiModelProperty("部门id")
private String jobId;
/**
* 部门名称
*/
//@ApiModelProperty("部门名称")
private String jobName;
/**
* 过期期限
*/
//@ApiModelProperty("过期期限")
@JsonFormat(pattern = "yyyyMM", timezone = "GMT+8")
private Date expire;
private String orgCode;
}
PostMan测试代码
文章来源:https://www.toymoban.com/news/detail-605160.html
控制台查看输出
文章来源地址https://www.toymoban.com/news/detail-605160.html
解析成JSON
{
"allArgs":[ // 所有入参
{
"bookId":123,
"bookImg":"testImg",
"bookIntro":"书籍简介",
"bookIsbn":"123213414",
"bookName":"test",
"bookPrice":12.77,
"bookPurchasedNumber":0
}
],
"argsType":{ // 入参实体类
"com.demo.mymaintest.entity.BookEntity":"bookEntity"
},
"classMethodLocation":"com.demo.mymaintest.controller.TestApiController.test", // 方法
"currentTimeMills":"2023-07-21 16:30:49", // 时间
"executeTimeMills":"9ms", // 运行时间
"nowTime":"2023-07-21 16:30:49", // 时间
"operation":"添加数据测试", // controller上面的注释
"remoteAddr":"0:0:0:0:0:0:0:1", // 这个其实是127.0.0.1 没有进行封装
"requestMethod":"POST",
"requestPath":"/api/add", // 路径
"responseData":"{msg=添加成功, code=200, data=BookEntity(bookId=123, bookIsbn=123213414, bookName=test, bookPrice=12.77, bookImg=testImg, bookIntro=书籍简介, bookPurchasedNumber=0)}",
"responseType":"com.demo.mymaintest.utils.R", // 所有返参
"username":"登录人从request中获取" // 根据项目详情从token或者session中获取登录人
}
如果你觉得对你有帮助的话,请点赞收藏
到了这里,关于基于AOP实现登录日志和操作日志(新手入门版)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!