依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
代码:
package com.talent.service.aop;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import io.netty.handler.codec.json.JsonObjectDecoder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.StopWatch;
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.core.DefaultParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* @program: Talent-Master
* @description: Api接口统一拦截日志aop
* @author: yarm.yang
* @create: 2020-01-15 11:22
*/
@Component
@Aspect
@Slf4j
public class ApiLogAop {
// 切点
@Pointcut("execution(* com.talent.controller..*.*(..)))")
public void pointcut(){}
@Around("pointcut()")
public Object handle(ProceedingJoinPoint joinPoint) throws Throwable {
Long watchTime = 0L;
try {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//IP地址
String ipAddr = getRemoteHost(request);
String url = request.getRequestURL().toString();
Map<String, String[]> parameterMap = request.getParameterMap();
String parameterStr = preHandle(parameterMap);
Map<String, String> reqMap = preHandle(joinPoint);
if(StringUtils.isNotBlank(parameterStr)){
log.info("请求源IP:{},请求URL:{},请求URL参数:{},请求JSON参数:{}", ipAddr, url, parameterStr, reqMap);
}else {
log.info("请求源IP:{},请求URL:{},请求JSON参数:{}", ipAddr, url, reqMap);
}
StopWatch stopWatch = new StopWatch();
// 执行目标方法
stopWatch.start();
Object result = joinPoint.proceed();
stopWatch.stop();
watchTime = stopWatch.getTime();
String respParam = postHandle(result);
log.info("请求源IP:{},请求URL:{},返回参数:{},请求时间:{}ms", ipAddr, url, respParam, watchTime);
return result;
}catch (Exception e){
log.error("日志aop拦截Exception异常:{}", JSONObject.toJSON(e.getMessage()).toString());
}catch (Throwable throwable){
log.error("日志aop拦截Throwable异常:{}", JSONObject.toJSON(throwable.getMessage()).toString());
}
return null;
}
/**
* @Description: 解析url带的参数
* @Param: [parameterMap]
* @Return: java.lang.String
* @Author: yarm.yang
* @Date: 2020/1/15 13:56
*/
private String preHandle(Map<String, String[]> parameterMap) {
String result = "";
if(parameterMap == null || parameterMap.size() == 0) return result;
StringBuffer sb = new StringBuffer();
for (Map.Entry entry : parameterMap.entrySet()){
String key = (String)entry.getKey();
String[] value = (String[])entry.getValue();
String valueArr = Arrays.toString(value);
String valueStr = "";
if(StringUtils.isNotBlank(valueArr) && valueArr.startsWith("[") && valueArr.endsWith("]")){
valueStr = valueArr.substring(1, valueArr.lastIndexOf(']'));
}
sb.append(key).append("=").append(valueStr).append("&");
}
result = sb.toString();
if(StringUtils.isNotBlank(result) && result.endsWith("&")){
result = result.substring(0, result.lastIndexOf('&'));
}
return result;
}
/**
* url入参数据,返回json
* @param joinPoint
* @param request
* @return
*/
private String preHandle(ProceedingJoinPoint joinPoint,HttpServletRequest request) {
String reqParam = "";
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method targetMethod = methodSignature.getMethod();
Annotation[] annotations = targetMethod.getAnnotations();
for (Annotation annotation : annotations) {
//此处可以改成自定义的注解
if (annotation.annotationType().equals(RequestMapping.class)) {
reqParam = JSON.toJSONString(request.getParameterMap());
break;
}
}
return reqParam;
}
/**
* @Description: json请求参数
* @Param: [joinPoint]
* @Return: java.util.Map<java.lang.String,java.lang.String>
* @Author: yarm.yang
* @Date: 2020/1/16 9:48
*/
private static Map<String, String> preHandle(ProceedingJoinPoint joinPoint) {
// 参数值
Object[] args = joinPoint.getArgs();
ParameterNameDiscoverer pnd = new DefaultParameterNameDiscoverer();
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
String[] parameterNames = pnd.getParameterNames(method);
Map<String, Object> paramMap = new HashMap<>(32);
for (int i = 0; i < parameterNames.length; i++) {
if(i == 0){
paramMap.put("p", args[i]);
}else {
// 约定好取第一个参数 直接过滤
continue;
// paramMap.put(parameterNames[i], args[i]);
}
}
// 返回map
Map<String, String> resultMap = new HashMap<>(32);
Object p = paramMap.get("p");
if(Objects.isNull(p)) return resultMap;
Map<String, Object> tempMap = JSON.parseObject(JSON.toJSONString(p),new TypeReference<Map<String,Object>>(){});
tempMap.forEach((k,v) -> {
resultMap.put(k, v + "");
});
return resultMap;
}
/**
* 返回数据
* @param retVal
* @return
*/
private String postHandle(Object retVal) {
if(null == retVal){
return "";
}
return JSON.toJSONString(retVal);
}
/**
* 获取目标主机的ip
* @param request
* @return
*/
private String getRemoteHost(HttpServletRequest request) {
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.getRemoteAddr();
}
return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
}
}