基于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中获取"
}
如果你觉得对你有帮助的话,请点赞收藏