在web项目监控中,我们往往需要知道用户访问了什么url路径,对其进行访问数据收集,持久化到日志文件中或者db中。
采用aop拦截http请求数据,能做到很好收集用户访问数据。
导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
核心代码:
package com.sb.hyh.aop;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
@Aspect
@Component
public class ServiceMonitor {
@Before("execution(* com.sb.hyh..*Controller.*(..))")
public void logAccess(JoinPoint joinPoint) {
System.out.println("Completed: " + joinPoint);
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
.getRequest();
String remoteAddr = getIpAddress(request);
String userAgent = request.getHeader("user-agent");
String requestUri = request.getRequestURI();
String method = request.getMethod();
Map<String, String[]> paramMap = request.getParameterMap();
StringBuffer params = new StringBuffer();
if (paramMap != null && !paramMap.isEmpty()) {
for (Map.Entry<String, String[]> param : paramMap.entrySet()) {
if ("".equals(params.toString())) {
params.append(param.getKey() + "=");
} else {
params.append("&" + param.getKey() + "=");
}
String paramValue = "";
if (param.getValue() != null && param.getValue().length > 0) {
paramValue = param.getValue()[0];
}
// 屏蔽密码获取
if (!"password".equals(param.getKey())) {
params.append(paramValue);
}
}
}
System.out.println("ip address:" + remoteAddr);
System.out.println("useragent:" + userAgent);
System.out.println("url:" + requestUri);
System.out.println("request method:" + method);
System.out.println("method params:" + params.toString());
System.out.println("---------------------------------");
}
public static String getIpAddress(HttpServletRequest request) {
String ip = request.getHeader("X-Forwarded-For");
if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
// 多次反向代理后会有多个ip值,第一个ip才是真实ip
int index = ip.indexOf(",");
if (index != -1) {
return ip.substring(0, index);
} else {
return ip;
}
}
ip = request.getHeader("X-Real-IP");
if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
return ip;
}
return request.getRemoteAddr();
}
}
测试url
http://localhost:8080/test?password=123
http://localhost:8080/?key=key1&value=value2
控制台输出,可以看到来源ip,useraent,访问url,访问参数
项目地址:https://github.com/hong0220/sb/tree/master/SB-Aop
qq群:Java技术交流群 116738274