基于AOP实现登录日志和操作日志
- 目录结构
- 代码
- PostMan测试代码
- 控制台查看输出
- 解析成JSON
- 如果你觉得对你有帮助的话,请点赞收藏
目录结构
代码
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;
@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;
@Aspect
@Component
public class SysLogAspect {
@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());
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.*;
@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;
@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;
@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;
private String userCode;
private String userName;
private String password;
private String realName;
private String mobile;
private String email;
private Long orgId;
private String orgName;
private Integer userType;
private String userDesc;
private String address;
private String fax;
private String postalcode;
private Integer status;
private String permissionType;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;
private String createBy;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date updateTime;
private String updateBy;
private Integer isDeleted;
private String orgAddress;
private String jobId;
private String jobName;
@JsonFormat(pattern = "yyyyMM", timezone = "GMT+8")
private Date expire;
private String orgCode;
}
PostMan测试代码
控制台查看输出
解析成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":"添加数据测试",
"remoteAddr":"0:0:0:0:0: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中获取"
}
如果你觉得对你有帮助的话,请点赞收藏