1前言: 在公司时候用的日志记录,可以可以用在controller来监控调取接口的ip和请求参数等信息,当然稍微改进也可以用在service等等。
2上代码
package com.xm.hardwaremanagement.util;
import com.alibaba.fastjson.JSON;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.Objects;
/**
* ServiceMonitorAspect
*
* @author LYS
* @date 2019/10/7
*/
@Component
@Aspect
public class LogMonitorAspect {
private static final String CONTENT_TYPE = "application/json";
private Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* 前置操作,日志记录
*
* @param point 切入点
*/
@Before("execution(public * com.xm.hardwaremanagement.controller.*Controller.*(..)) || execution(public * com.xm.hardwaremanagement.upload.*Controller.*(..))")
public void beforeLog(JoinPoint point) {
//获取HttpServletRequest
HttpServletRequest request=getRequest();
String contentType = request.getContentType();
if (CONTENT_TYPE.equals(contentType)) {
//post请求体json格式请求
//获取请求参数
StringBuilder logParams = getJsonParams(point);
logger.info("【请求IP】:{},【请求URL】:{},【请求类名】:{},【请求方法名】:{},【请求参数1】:{}", getIpAddress(), request.getRequestURL(), point.getSignature().getDeclaringTypeName(), point.getSignature().getName(), logParams);
} else {
// 非post请求体json格式请求,例如get请求,fordata格式
Map<String, String[]> parameterMap = request.getParameterMap();
logger.info("【请求IP】:{},【请求URL】:{},【请求类名】:{},【请求方法名】:{},【请求参数2】:{}", getIpAddress(), request.getRequestURL(), point.getSignature().getDeclaringTypeName(), point.getSignature().getName(), JSON.toJSONString(parameterMap));
}
}
/**
* 得到请求参数
* @param point
* @return
*/
private StringBuilder getJsonParams(JoinPoint point) {
StringBuilder sb = new StringBuilder();
Object[] params = point.getArgs();
sb.append(JSON.toJSONString(params[0]));
return sb;
}
/**
* 得到HttpServletRequest对象
* @return
*/
public static HttpServletRequest getRequest() {
return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
}
/**
* 获取用户真实IP地址,不使用request.getRemoteAddr();的原因是有可能用户使用了代理软件方式避免真实IP地址,
* 参考文章: http://developer.51cto.com/art/201111/305181.htm
* <p>
* 可是,如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP值,究竟哪个才是真正的用户端的真实IP呢?
* 答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。
* <p>
* 如:X-Forwarded-For:192.168.1.110, 192.168.1.120, 192.168.1.130,
* 192.168.1.100
* <p>
* 用户真实IP为: 192.168.1.110
*
* 本地请求ip为0:0:0:0:0:0:0:1
*/
public static String getIpAddress() {
HttpServletRequest request=getRequest();
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
}
2.1执行结果
15:30:38.171 INFO [http-nio-7971-exec-2] [c.x.h.configuration.LogMonitorAspect:57] [65ea58b9c76949fdbc7889bb6050c828] - 【请求IP】:0:0:0:0:0:0:0:1,【请求URL】:http://localhost:7971/employee/deviceSearchPersonState,【请求类名】:com.xm.hardwaremanagement.controller.EmployeeController,【请求方法名】:deviceSearchPersonState,【请求参数1】:{"equipmentSerialNumber":"84E0F4241CC351FA","user":[{"jobNumber":"A26510D72AF34B7984EECFEB17FA400B"}]}
- 完结