001package top.cenze.utils.aspect; 002 003import cn.hutool.core.collection.CollectionUtil; 004import cn.hutool.core.util.ArrayUtil; 005import cn.hutool.core.util.ObjectUtil; 006import cn.hutool.core.util.StrUtil; 007import com.alibaba.fastjson.JSON; 008import com.alibaba.fastjson.JSONObject; 009import lombok.SneakyThrows; 010import lombok.extern.slf4j.Slf4j; 011import org.aspectj.lang.JoinPoint; 012import org.aspectj.lang.reflect.CodeSignature; 013import org.aspectj.lang.reflect.MethodSignature; 014import org.omg.CORBA.UNKNOWN; 015import org.springframework.core.annotation.AnnotationFilter; 016 017import javax.servlet.http.HttpServletRequest; 018import javax.servlet.http.HttpServletResponse; 019import java.lang.reflect.Field; 020import java.lang.reflect.Method; 021import java.net.InetAddress; 022import java.net.UnknownHostException; 023import java.util.HashMap; 024import java.util.Map; 025 026/** 027 * AOP工具 028 */ 029@Slf4j 030public class AspectUtil { 031 // 多次反向代理后会有多个ip值 的分割符 032 private final static String IP_UTILS_FLAG = ","; 033 // 未知IP 034 private final static String UNKNOWN = "unknown"; 035 // 本地 IP 036 private final static String LOCALHOST_IP = "0:0:0:0:0:0:0:1"; 037 private final static String LOCALHOST_IP1 = "127.0.0.1"; 038 039 040 /** 041 * 获取所有请求参数 042 * 支持基础类型与对象及自定义对象混合情况,如果是对象或自定义对象,提取其成员变量 043 * @param point 044 * @return 045 */ 046 public static Map<String, Object> getRequestAllParams(JoinPoint point) { 047 Map<String, Object> params = getRequestParams(point); 048 log.info("getRequestAllParams params: {}", JSON.toJSONString(params)); 049 050 Map<String, Object> allParams = new HashMap<>(); 051 if (CollectionUtil.isNotEmpty(allParams)) { 052 for (Map.Entry<String, Object> entry : allParams.entrySet()) { 053 String name = entry.getKey(); 054 log.info("getRequestAllParams name: {}", name); 055 Object obj = entry.getValue(); 056 log.info("getRequestAllParams obj: {}", JSON.toJSONString(obj)); 057 // java基础类型 058 if (isJavaLang(obj)) { 059 params.put(name, obj); 060 } 061 // 对象或自定义对象 062 else { 063 Map<String, Object> paramsByObj = getParamsByObj(obj); 064 log.info("getRequestAllParams paramsByObj: {}", JSON.toJSONString(paramsByObj)); 065 if (CollectionUtil.isNotEmpty(paramsByObj)) { 066 allParams.putAll(paramsByObj); 067 } 068 } 069 } 070 } 071 072 return allParams; 073 } 074 075 /** 076 * 获取所有请求参数 077 * 支持基础类型与对象及自定义对象混合情况,不提取对象或自定义对象内的成员变量 078 * @param point 079 * @return 080 */ 081 public static Map<String, Object> getRequestParams(JoinPoint point) { 082 Map<String, Object> params = new HashMap<>(); 083 084 MethodSignature signature = (MethodSignature) point.getSignature(); 085 log.info("getRequestParams signature: {}", JSON.toJSONString(signature)); 086// Method method = signature.getMethod(); 087 088 // 请求的方法所有参数值 089 Object[] args = point.getArgs(); 090 log.info("getRequestParams args: {}", JSON.toJSONString(args)); 091 // 请求的方法所有参数名称 092 String[] paramNames = ((CodeSignature)signature).getParameterNames(); 093 // 请求的方法参数名称 094// LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer(); 095// String[] paramNames = u.getParameterNames(method); 096 log.info("getRequestParams paramNames: {}", JSON.toJSONString(paramNames)); 097 098 if (ObjectUtil.isNotEmpty(args) && ObjectUtil.isNotEmpty(paramNames)) { 099 for (int i = 0; i < args.length; i++) { 100 Object obj = args[i]; 101 // 请求参数 102 if (obj instanceof HttpServletRequest) { 103 String name = paramNames[i]; 104 params.put(name, obj); 105 } 106 } 107 } 108 109 return params; 110 } 111 112 public static Object getParamByName(JoinPoint point, String name) { 113 MethodSignature signature = (MethodSignature) point.getSignature(); 114 log.info("getParamByName signature: {}", JSON.toJSONString(signature)); 115 116 // 请求的方法所有参数值 117 Object[] args = point.getArgs(); 118 log.info("getParamByName args: {}", JSON.toJSONString(args)); 119 if (ObjectUtil.isNotEmpty(args)) { 120 for (Object obj : args) { 121 JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(obj)); 122 log.info("getParamByName jsonObject: {}", JSON.toJSONString(jsonObject)); 123 if (jsonObject.containsKey(name)) { 124 return jsonObject.get(name); 125 } 126 } 127 } 128 129 return null; 130 } 131 132 /** 133 * 获取所有响应参数 134 * 支持基础类型与对象及自定义对象混合情况,如果是对象或自定义对象,提取其成员变量 135 * @param point 136 * @return 137 */ 138 public static Map<String, Object> getResponseAllParams(JoinPoint point) { 139 Map<String, Object> params = getResponseParams(point); 140 141 Map<String, Object> allParams = new HashMap<>(); 142 if (CollectionUtil.isNotEmpty(allParams)) { 143 for (Map.Entry<String, Object> entry : allParams.entrySet()) { 144 String name = entry.getKey(); 145 Object obj = entry.getValue(); 146 // java基础类型 147 if (isJavaLang(obj)) { 148 params.put(name, obj); 149 } 150 // 对象或自定义对象 151 else { 152 Map<String, Object> paramsByObj = getParamsByObj(obj); 153 if (CollectionUtil.isNotEmpty(paramsByObj)) { 154 allParams.putAll(paramsByObj); 155 } 156 } 157 } 158 } 159 160 return allParams; 161 } 162 163 /** 164 * 获取所有响应参数 165 * 支持基础类型与对象及自定义对象混合情况,不提取对象或自定义对象内的成员变量 166 * @param point 167 * @return 168 */ 169 public static Map<String, Object> getResponseParams(JoinPoint point) { 170 Map<String, Object> params = new HashMap<>(); 171 172 MethodSignature signature = (MethodSignature) point.getSignature(); 173 174 // 请求的方法所有参数值 175 Object[] args = point.getArgs(); 176 // 请求的方法所有参数名称 177 String[] paramNames = ((CodeSignature)signature).getParameterNames(); 178 179 if (ObjectUtil.isNotEmpty(args) && ObjectUtil.isNotEmpty(paramNames)) { 180 for (int i = 0; i < args.length; i++) { 181 Object obj = args[i]; 182 // 请求参数 183 if (obj instanceof HttpServletResponse) { 184 String name = paramNames[i]; 185 params.put(name, obj); 186 } 187 } 188 } 189 190 return params; 191 } 192 193 /** 194 * 获取对象内成员变量Map 195 * @param obj 196 * @return 197 */ 198 public static Map<String, Object> getParamsByObj(Object obj) { 199 Map<String, Object> params = new HashMap<>(); 200 201 Field[] fields = obj.getClass().getDeclaredFields(); 202 if (ObjectUtil.isNotEmpty(fields)) { 203 for (Field field : fields) { 204 field.setAccessible(true); 205 String key = field.getName(); 206 try { 207 Object val = field.get(obj); 208 209 if (ObjectUtil.isNotEmpty(val)) { 210 params.put(key, val); 211 } 212 } catch (IllegalAccessException e) { 213 e.printStackTrace(); 214 } 215 } 216 } 217 218 return params; 219 } 220 221 @SneakyThrows 222 public static void setParamByName(JoinPoint point, String name, Object val) { 223 MethodSignature methodSignature = (MethodSignature) point.getSignature(); 224 final String[] names = methodSignature.getParameterNames(); // 获取参数的名字 225 log.info("setParamByName names: {}", JSON.toJSONString(names)); 226 final Object[] args = point.getArgs(); // 获取参数的值 227 log.info("setParamByName args: {}", JSON.toJSONString(args)); 228 229 if (ObjectUtil.isNull(names) || ObjectUtil.isNull(args) || 230 0 == names.length || 0 == args.length) { 231 return; 232 } 233 234 // 直接查看参数名匹配(参数为基础类型,直接设置值) 235 int idx = ArrayUtil.indexOfIgnoreCase(names, name); 236 log.info("setParamByName idx: {}", idx); 237 if (idx >= 0) { 238 // 如果是基础类型,直接设置值 239 if (isJavaLang(args[idx])) { 240 args[idx] = val; 241 } 242 } 243 // 反射方式查找,并修改值 244 else { 245 for (Object obj : args) { 246 Method setPlatformIdMethod = obj.getClass().getMethod("setPlatformId", Long.class); 247 log.info("setParamByName args2: {}", JSON.toJSONString(args)); 248 if (ObjectUtil.isNull(setPlatformIdMethod)) { 249 continue; 250 } 251 252 setPlatformIdMethod.invoke(obj, val); 253 log.info("setParamByName args3: {}", JSON.toJSONString(args)); 254 } 255 } 256 } 257 258 /** 259 * 获取request中的IP 260 * 261 * @param request 262 * @return 263 */ 264 public static String getIpAddress(HttpServletRequest request) { 265 if (request == null) { 266 return "unknown"; 267 } 268 269 String ip = null; 270 try { 271 // 以下两个获取在k8s中,将真实的客户端IP,放到了x-Original-Forwarded-For。而将WAF的回源地址放到了 x-Forwarded-For了。 272 ip = request.getHeader("X-Original-Forwarded-For"); 273 if (StrUtil.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) { 274 ip = request.getHeader("X-Forwarded-For"); 275 } 276 // 获取nginx等代理的ip 277 if (StrUtil.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) { 278 ip = request.getHeader("x-forwarded-for"); 279 } 280 if (StrUtil.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) { 281 ip = request.getHeader("Proxy-Client-IP"); 282 } 283 if (StrUtil.isEmpty(ip) || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { 284 ip = request.getHeader("WL-Proxy-Client-IP"); 285 } 286 if (StrUtil.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) { 287 ip = request.getHeader("HTTP_CLIENT_IP"); 288 } 289 if (StrUtil.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) { 290 ip = request.getHeader("HTTP_X_FORWARDED_FOR"); 291 } 292 if (StrUtil.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) { 293 ip = request.getHeader("X-Real-IP"); 294 } 295 // 兼容k8s集群获取ip 296 if (StrUtil.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) { 297 ip = request.getRemoteAddr(); 298 if (LOCALHOST_IP1.equalsIgnoreCase(ip) || LOCALHOST_IP.equalsIgnoreCase(ip)) { 299 // 根据网卡取本机配置的IP 300 InetAddress iNet = null; 301 try { 302 iNet = InetAddress.getLocalHost(); 303 } catch (UnknownHostException e) { 304 log.error("getClientIp error: ", e); 305 } 306 ip = iNet.getHostAddress(); 307 } 308 } 309 } catch (Exception e) { 310 log.error("IPUtils ERROR ", e); 311 } 312 313 // 使用代理,则获取第一个IP地址 314 if (StrUtil.isNotEmpty(ip) && ip.indexOf(IP_UTILS_FLAG) > 0) { 315 ip = ip.substring(0, ip.indexOf(IP_UTILS_FLAG)); 316 } 317 318 return ip; 319 } 320 321 /** 322 * 判断是否为JAVA基础类型 323 * @param obj 324 * @return 325 */ 326 public static boolean isJavaLang(Object obj) { 327 return AnnotationFilter.PLAIN.matches(obj.getClass()); 328// return obj.getClass().getName().startsWith("java.lang"); 329 } 330}