feat:
- 添加AopLog - 添加AopController测试
This commit is contained in:
parent
24724b76fe
commit
b7a05a1ef2
4
pom.xml
4
pom.xml
@ -48,6 +48,10 @@
|
|||||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||||
<version>3.0.3</version>
|
<version>3.0.3</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-aop</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.mysql</groupId>
|
<groupId>com.mysql</groupId>
|
||||||
<artifactId>mysql-connector-j</artifactId>
|
<artifactId>mysql-connector-j</artifactId>
|
||||||
|
|||||||
185
src/main/java/asia/yulinling/workflow/aspectj/AopLog.java
Normal file
185
src/main/java/asia/yulinling/workflow/aspectj/AopLog.java
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
package asia.yulinling.workflow.aspectj;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
|
import cn.hutool.http.useragent.UserAgent;
|
||||||
|
import cn.hutool.http.useragent.UserAgentUtil;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import cn.hutool.log.Log;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
|
import org.aspectj.lang.Signature;
|
||||||
|
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.net.InetAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 使用 aop 切面记录请求日志信息
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author yulinling
|
||||||
|
* @since 2025/6/5
|
||||||
|
*/
|
||||||
|
@Aspect
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class AopLog {
|
||||||
|
/**
|
||||||
|
* 切入点
|
||||||
|
*/
|
||||||
|
@Pointcut("execution(public * asia.yulinling.workflow.controller.*Controller.*(..))")
|
||||||
|
public void log() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 环绕操作
|
||||||
|
*
|
||||||
|
* @param joinPoint 切入点
|
||||||
|
* @return 原方法返回值
|
||||||
|
* @throws Throwable 异常信息
|
||||||
|
*/
|
||||||
|
@Around("log()")
|
||||||
|
public Object aroundLog(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||||
|
// 开始打印请求日志
|
||||||
|
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||||
|
HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();
|
||||||
|
|
||||||
|
// 打印请求相关参数
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
Object result = joinPoint.proceed();
|
||||||
|
String header = request.getHeader("User-Agent");
|
||||||
|
UserAgent ua = UserAgentUtil.parse(header);
|
||||||
|
final Log l = Log.builder()
|
||||||
|
.threadId(Thread.currentThread().getName())
|
||||||
|
.threadName(Thread.currentThread().getName())
|
||||||
|
.ip(getIp(request))
|
||||||
|
.url(request.getRequestURI())
|
||||||
|
.httpMethod(request.getMethod())
|
||||||
|
.classMethod(joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName())
|
||||||
|
.requestParams(getNameAndValue(joinPoint))
|
||||||
|
.result(result)
|
||||||
|
.timeCost(System.currentTimeMillis() - startTime)
|
||||||
|
.userAgent(header)
|
||||||
|
.browser(ua.getBrowser().toString())
|
||||||
|
.os(ua.getOs().toString())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
log.info("Request Log Info:{}", JSONUtil.toJsonStr(l));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取方法参数名和参数值
|
||||||
|
* @param joinPoint 切入点
|
||||||
|
* @return 接口参数和参数值
|
||||||
|
*/
|
||||||
|
private Map<String, Object> getNameAndValue(ProceedingJoinPoint joinPoint) {
|
||||||
|
final Signature signature = joinPoint.getSignature();
|
||||||
|
MethodSignature methodSignature = (MethodSignature) signature;
|
||||||
|
final String[] names = methodSignature.getParameterNames();
|
||||||
|
final Object[] args = joinPoint.getArgs();
|
||||||
|
|
||||||
|
if (ArrayUtil.isEmpty(names) || ArrayUtil.isEmpty(args)) {
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
if (names.length != args.length) {
|
||||||
|
log.warn("{}方法参数名和参数数量不一致", methodSignature.getName());
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
for (int i = 0; i < names.length; i++) {
|
||||||
|
map.put(names[i], args[i]);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取ip地址
|
||||||
|
* @param request 请求体
|
||||||
|
* @return 返回ip地址
|
||||||
|
*/
|
||||||
|
public static String getIp(HttpServletRequest request) {
|
||||||
|
String ip = request.getHeader("X-Forwarded-For");
|
||||||
|
if (isInvalidIp(ip)) {
|
||||||
|
ip = request.getHeader("Proxy-Client-IP");
|
||||||
|
}
|
||||||
|
if (isInvalidIp(ip)) {
|
||||||
|
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||||
|
}
|
||||||
|
if (isInvalidIp(ip)) {
|
||||||
|
ip = request.getHeader("HTTP_CLIENT_IP");
|
||||||
|
}
|
||||||
|
if (isInvalidIp(ip)) {
|
||||||
|
ip = request.getRemoteAddr();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理多级代理
|
||||||
|
if (ip != null && ip.contains(",")) {
|
||||||
|
ip = ip.split(",")[0].trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 本地地址处理
|
||||||
|
if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip)) {
|
||||||
|
try {
|
||||||
|
ip = InetAddress.getLocalHost().getHostAddress();
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
log.error("获取本地 IP 失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isInvalidIp(String ip) {
|
||||||
|
return ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip);
|
||||||
|
}
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
static class Log {
|
||||||
|
// 线程id
|
||||||
|
private String threadId;
|
||||||
|
// 线程名称
|
||||||
|
private String threadName;
|
||||||
|
// ip
|
||||||
|
private String ip;
|
||||||
|
// url
|
||||||
|
private String url;
|
||||||
|
// http方法 GET POST PUT DELETE PATCH
|
||||||
|
private String httpMethod;
|
||||||
|
// 类方法
|
||||||
|
private String classMethod;
|
||||||
|
// 请求参数
|
||||||
|
private Object requestParams;
|
||||||
|
// 返回参数
|
||||||
|
private Object result;
|
||||||
|
// 接口耗时
|
||||||
|
private Long timeCost;
|
||||||
|
// 操作系统
|
||||||
|
private String os;
|
||||||
|
// 浏览器
|
||||||
|
private String browser;
|
||||||
|
// user-agent
|
||||||
|
private String userAgent;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
package asia.yulinling.workflow.controller;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Dict;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 测试aop
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author yulinling
|
||||||
|
* @since 2025/6/5
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
public class TestController {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试方法 GET
|
||||||
|
* @param who 测试参数
|
||||||
|
* @return {@link Dict}
|
||||||
|
*/
|
||||||
|
@GetMapping("/test")
|
||||||
|
public Dict test(String who) {
|
||||||
|
return Dict.create().set("who", who);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试方法 POST
|
||||||
|
* @param map 请求的json参数
|
||||||
|
* @return {@link Dict}
|
||||||
|
*/
|
||||||
|
@PostMapping("/testJson")
|
||||||
|
public Dict testJson(@RequestBody Map<String, Object> map) {
|
||||||
|
final String jsonStr = JSONUtil.toJsonStr(map);
|
||||||
|
log.info(jsonStr);
|
||||||
|
return Dict.create().set("json", jsonStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,3 +1,6 @@
|
|||||||
|
# ????
|
||||||
|
server.port=8080
|
||||||
|
server.servlet.context-path=/demo
|
||||||
|
|
||||||
# mysql??
|
# mysql??
|
||||||
spring.datasource.url=jdbc:mysql://122.152.201.90:9912/workflow?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=GMT%2B8
|
spring.datasource.url=jdbc:mysql://122.152.201.90:9912/workflow?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=GMT%2B8
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user