aop实现打印相关日志信息
这里会去截取请求中的参数
主要作用: 获取一次请求的访问ip, url, 分支机构, 方法名, 关键字, 访问时间, 请求唯一标识, 参数等, 然后统一打印出来, 方便查看日志排查问题
主要实现: 通过反射的方式将请求中的参数的值获取到.(一种是参数为一个对象的情况, 另一种是参数为多个单独参数的情况, 都进行了分别的处理)
package xxx; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.core.ParameterNameDiscoverer; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.multipart.MultipartFile; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @Component @Aspect @Slf4j public class LogAop { // @Value("${logParamKeywords}") private final String logParamKeywords = "registNo,taskId,businessId"; @Before(value = "execution(* xxx..*Api.*(..))") public void beforeMethod(JoinPoint pjp){ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String methodName = pjp.getSignature().getName(); Object[] args = pjp.getArgs(); String []keywords = logParamKeywords == null? null : logParamKeywords.split(","); Map<String, String> fieldMap = new HashMap<>(); String k = ""; String v = ""; String param; try { if (args != null) { if (args.length == 1 && !this.isBaseType(args[0].getClass())) { fieldMap = getfieldsValue(args[0], keywords); param = JSON.toJSONString(args[0]); } else { Map<String, Object> paramMap = this.getParamValue(pjp); param = JSON.toJSONString(paramMap); if (keywords != null && paramMap != null && !paramMap.isEmpty()) { for (String keyword : keywords) { if (paramMap.get(keyword) != null) { fieldMap.put(keyword, String.valueOf(paramMap.get(keyword))); break; } } } } } else { param = "参数为空!"; } if (fieldMap != null && !fieldMap.isEmpty()) { k = String.valueOf(fieldMap.keySet().toArray()[0]); v = fieldMap.get(k); } ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes != null ? attributes.getRequest() : null; String ip = "request为空"; String url = "request为空"; String comCode = "request为空"; if (request != null) { ip = request.getRemoteAddr(); url = request.getRequestURL().toString(); comCode = request.getHeader("comCode"); } log.info("\n===============================================================================================================\n" + "=====================API访问请求信息:=============================================================================\n" + "=====================ip: "+ip+"\n" + "=====================url: "+url+"\n" + "=====================sharding_comCode: "+comCode+"\n" + "=====================方法名: "+methodName+"\n" + "=====================关键字: "+k+"["+v+"]\n" + "=====================时间: "+df.format(new Date())+"\n" + "=====================参数: "+param+"\n" + "===============================================================================================================\n" + "==============================================================================================================="); } catch (Exception e) { e.printStackTrace(); } } /** * @param obj * @param keywords */ private Map<String, String> getfieldsValue(Object obj, String[] keywords) { if (keywords == null) { return null; } Map<String, String> fieldMap = new HashMap<>(); List<Field> fields = this.getFields(obj); for (String field : keywords) { for (Field item : fields) { item.setAccessible(true); try { // 字段名 if (item.getName().equals(field) && item.get(obj) != null) { //赋值 fieldMap.put(field, String.valueOf(item.get(obj))); } } catch (Exception e) { e.printStackTrace(); } } if (!fieldMap.isEmpty()) { return fieldMap; } } return fieldMap; } /** * 判断是否是基本数据类型以及常用数据类型 * @param className * @return */ private boolean isBaseType(Class className) { return className.equals(Integer.class) || className.equals(int.class) || className.equals(Byte.class) || className.equals(byte.class) || className.equals(Long.class) || className.equals(long.class) || className.equals(Double.class) || className.equals(double.class) || className.equals(Float.class) || className.equals(float.class) || className.equals(Character.class) || className.equals(char.class) || className.equals(Short.class) || className.equals(short.class) || className.equals(Boolean.class) || className.equals(boolean.class) || className.equals(BigDecimal.class) || className.equals(String.class); } /** * 返回该类及其父类的所有声明的字段,即包括public、private和proteced修饰的字段, 排除了Object父类 * @param obj * @return */ private List<Field> getFields(Object obj) { Class<?> tempClass = obj.getClass(); List<Field> fieldList = new ArrayList<>(); while (tempClass != null && !"java.lang.object".equalsIgnoreCase(tempClass.getName())) { fieldList.addAll(Arrays.asList(tempClass.getDeclaredFields())); tempClass = tempClass.getSuperclass(); } return fieldList; } /** * 传入参数为多个单独参数的时候, 取各个参数值及结果到map中 * @param pjp * @return */ private Map<String, Object> getParamValue(JoinPoint pjp) { Object[] args = pjp.getArgs(); String classType = pjp.getTarget().getClass().getName(); String methodName = pjp.getSignature().getName(); Map<String, Object> paramMap = new LinkedHashMap<>(2); try { // 参数值 Class<?>[] classes = new Class[args.length]; boolean noClassesFlag = false; for (int k = 0; k < args.length; k++) { if (args[k] instanceof MultipartFile || args[k] instanceof ServletRequest || args[k] instanceof ServletResponse) { return paramMap; } if (args[k] == null) { noClassesFlag = true; break; } if (!args[k].getClass().isPrimitive()) { // 当方法参数是封装类型 Class s = args[k].getClass(); classes[k] = s == null ? args[k].getClass() : s; } } ParameterNameDiscoverer pnd = new DefaultParameterNameDiscoverer(); // 获取指定的方法 Method method = null; if (noClassesFlag) { Method[] methods = Class.forName(classType).getDeclaredMethods(); for (Method ms : methods) { String name = ms.getName(); Class<?>[] paramTypes = ms.getParameterTypes(); if (methodName.equals(name) && classes.length == paramTypes.length) { method = Class.forName(classType).getMethod(methodName, paramTypes); } } if (method == null) { return paramMap; } } else { method = Class.forName(classType).getMethod(methodName, classes); } // 参数名 String[] parameterNames = pnd.getParameterNames(method); // 通过map封装参数和参数值 if (parameterNames != null) { for (int i = 0; i < parameterNames.length; i++) { paramMap.put(parameterNames[i], args[i]); } } } catch (Exception e) { e.printStackTrace(); } return paramMap; } }