开头

日志在一个项目中是不可或缺的,如果是单一的API服务端,可采用切面拦截所有Controller的请求,已达到目的,若是前后端不分离项目,则使用注解会更佳。

首先定义注解

@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface WebLog {
boolean flag() default true;
String title() default "";
}
复制代码
我在这里定义了一个是否使用的标志和标题,大家可以拓展,以下是解释注解的说明:
* @Target 注解可修饰的对象范围,ElementType.METHOD 作用于方法,ElementType.TYPE 作用于类
* (ElementType)取值有:
*     1.CONSTRUCTOR:用于描述构造器
*     2.FIELD:用于描述域
*     3.LOCAL_VARIABLE:用于描述局部变量
*     4.METHOD:用于描述方法
*     5.PACKAGE:用于描述包
*     6.PARAMETER:用于描述参数
*     7.TYPE:用于描述类、接口(包括注解类型) 或enum声明
* @Retention 定义了该Annotation被保留的时间长短:某些Annotation仅出现在源代码中,而被编译器丢弃;
* 而另一些却被编译在class文件中;编译在class文件中的Annotation可能会被虚拟机忽略,
* 而另一些在class被装载时将被读取(请注意并不影响class的执行,因为Annotation与class在使用上是被分离的)。
* 使用这个meta-Annotation可以对 Annotation的“生命周期”限制。
* (RetentionPoicy)取值有:
*     1.SOURCE:在源文件中有效(即源文件保留)
*     2.CLASS:在class文件中有效(即class保留)
*     3.RUNTIME:在运行时有效(即运行时保留)
*
* @Inherited
* 元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。
* 如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。
复制代码
第二步添加切面
@Aspect
@Slf4j
@Component
public class WebLogAspect {
@Pointcut(value = "@annotation(com.qqri.api.annotation.WebLog)")
public void webLog() {
}
@Before(value = "webLog()")
public void doBefore(JoinPoint joinPoint) throws Exception {
WebLog webLog = getAnnotationLog(joinPoint);
//获取是否有注解
if (webLog == null) {
return;
}
boolean flag = webLog.flag();
if (flag) {
// 接收到请求,记录请求内容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// 记录下请求内容
log.info("Description :" + webLog.title());
log.info("URL : " + request.getRequestURL().toString());
log.info("HTTP_METHOD : " + request.getMethod());
log.info("IP : " + IpUtil.getIpAddress(request));
log.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
log.info("ARGS : " + Arrays.toString(joinPoint.getArgs()));
}
}
/**
* 是否存在注解,如果存在就获取
*/
private WebLog getAnnotationLog(JoinPoint joinPoint) throws Exception {
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
if (method != null) {
return method.getAnnotation(WebLog.class);
}
return null;
}
@AfterReturning(returning = "reValue", pointcut = "webLog()")
public void doAfterReturning(JoinPoint joinPoint, Object reValue) throws Exception {
WebLog webLog = getAnnotationLog(joinPoint);
if (webLog == null) {
return;
}
boolean flag = webLog.flag();
if (flag) {
// 处理完请求,返回内容
log.info("RESPONSE : " + reValue);
}
}
}

复制代码

切点为定义的日志注解,从请求方法中获取是否包含该注解,并且flag标志为true。

在切面中可以做更多的操作,例如保存到数据库,保存这个步骤建议作为异步化处理。

第三步添加注解

在接口方法上添加注解@WebLog()

@WebLog(title = "获取今日运势接口")
@RequestLimit(second = 2, maxCount = 5)
@ApiOperation(value = "获取今日运势接口", notes = "获取今日运势接口")
@GetMapping("/get/{qq}")
public RestfulResponse getFortuneOfToday(@PathVariable String qq) {
return qrFortuneService.getFortuneOfToday(qq);
}

复制代码

日志打印效果如下:

2019-08-02 09:17:59.243 INFO 8580 --- [io-8081-exec-16] com.qqri.api.aspect.WebLogAspect : Description :登录接口
2019-08-02 09:17:59.243 INFO 8580 --- [io-8081-exec-16] com.qqri.api.aspect.WebLogAspect : URL : http://localhost:8081/qr_admin_main/login
2019-08-02 09:17:59.243 INFO 8580 --- [io-8081-exec-16] com.qqri.api.aspect.WebLogAspect : HTTP_METHOD : POST
2019-08-02 09:17:59.244 INFO 8580 --- [io-8081-exec-16] com.qqri.api.aspect.WebLogAspect : IP : 0:0:0:0:0:0:0:1
2019-08-02 09:17:59.244 INFO 8580 --- [io-8081-exec-16] com.qqri.api.aspect.WebLogAspect : CLASS_METHOD : com.qqri.api.controller.admin.QrAdminMainController.login
2019-08-02 09:17:59.244 INFO 8580 --- [io-8081-exec-16] com.qqri.api.aspect.WebLogAspect : ARGS : [QrUser(userId=null, deptId=null, loginName=admin, userName=null, userType=null, email=null, phonenumber=null, sex=null, avatar=null, password=xxx.., salt=null, status=null, delFlag=null, loginIp=null, loginDate=null, createBy=null, createTime=null, updateBy=null, updateTime=null, remark=null), org.apache.shiro.web.servlet.ShiroHttpServletRequest@217b8748]
2019-08-02 09:17:59.908 INFO 8580 --- [io-8081-exec-16] com.qqri.api.aspect.WebLogAspect : RESPONSE : RestfulResponse(status=30011, msg=登陆成功, data=null)
复制代码