1.定义切点
1.1 类上面加上下方注解
@Aspect // 定义一个切面
@Configuration //配置类
1.2 指定切点位置
@Pointcut("execution(* com.example.demo.controller..*Controller.*(..))")
public void excudeService() {
}
其中execution表达式可以自行扩展.
此处表示com.example.demo.controller包及其子包中所有以Controller结尾的类中的所有方法.
简单扩展
execution(* com.example.demo.controller..Controller.(..))
-
controller后有两个点
表示本身及其子包,改为一个点,则只表示当前包下
-
*Controller
以Controller结尾
2.切点实现
上方定义了实现方法excudeService()
2.1 方法上加上注解
// 切点实现
@Around("excudeService()")
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
}
2.2 编写具体代码
写完你不用启动项目,idea就会帮你推断哪些地方会使用上.
3.参考代码
package com.example.demo.config;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
/**
* @Description: 切面实现 controller请求与返回数据的打印
* @Class: LogRecordAspect
* @Author: Yiang37
* @Date: 2021/8/6 11:40
* @Version: 1.0
*/
@Configuration
@Aspect // 定义一个切面
@Slf4j //代码直接写log.xx即可
public class LogRecordAspect {
// 定义切点
@Pointcut("execution(* com.example.demo.controller..*Controller.*(..))")
public void excudeService() {
}
// 切点实现
@Around("excudeService()")
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
log.info("----------------------------------------------------");
// 1.请求处理
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
assert servletRequestAttributes != null;
HttpServletRequest request = servletRequestAttributes.getRequest();
String uri = request.getRequestURI();
// 获取请求方式
String method = request.getMethod();
// GET
if ("GET".equals(method)) {
StringBuilder stringBuilder = new StringBuilder();
// request.getParameterMap()只能获取Get方式传入的数据
Map<String, String[]> parameterMap = request.getParameterMap();
for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
stringBuilder.append(entry.getKey()).append(" - ").append(Arrays.toString(entry.getValue())).append("
");
}
// 去掉最后一个多余的回车符
stringBuilder.deleteCharAt(stringBuilder.length()-1);
log.info(">> | 请求开始,URI: '{}', method: '{}', Data:
{}", uri, method, stringBuilder);
}
// POST
if ("POST".equals(method)) {
try (BufferedReader bufferedReader = new BufferedReader(request.getReader())) {
// 每次读取一行
StringBuilder stringBuilder = new StringBuilder();
String str;
while ((str = bufferedReader.readLine()) != null) {
stringBuilder.append(str);
}
// 美化下stringBuilder这个json字符串的格式
String prettyJsonStr = JSON.toJSONString(JSONObject.parseObject(stringBuilder.toString()), SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteDateUseDateFormat);
log.info(">> | 请求开始,URI: '{}', method: '{}', Data:
{}", uri, method, prettyJsonStr);
} catch (IOException e) {
log.error("Post参数请求解析失败:{}", e.getMessage());
}
}
// 2.返回处理
Object result = pjp.proceed();
log.info("<< | 请求结束,controller返回值:
" + JSON.toJSON(result));
log.info("----------------------------------------------------");
return result;
}
}
4.相关pom包
<!-- aop -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- log4j2 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<!-- fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
日志相关使用可以看我这篇文章: