springAop之 记录登入日志

来源:互联网 发布:高仿lv女包淘宝店铺 编辑:程序博客网 时间:2024/05/20 21:19

注解类

import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public @interface AuditLog {    boolean skip() default false;}

Aop运用

/** * Aspect for logging execution of service and repository Spring components. * <p> * By default, it only runs with the "dev" profile. */@Aspectpublic class LoggingAspect {  private final Logger log = LoggerFactory.getLogger(LoggingAspect.class);  @Inject  private LoggingService loggingService;  private final Environment env;  @Value("${app.auditLogFlag.printGet}")  private boolean logFlag;  ObjectMapper mapper = new ObjectMapper();  public LoggingAspect(Environment env) {    this.env = env;  }  /**   * Pointcut that matches all repositories, services and Web REST endpoints.   */  @Pointcut("within(com.qingxing.ManagerComplex.api.web.*.*Resource)")  public void loggingPointcut() {    // Method is empty as this is just a Pointcut, the implementations are in the advices.  }  /**   * Advice that logs methods throwing exceptions.   */  @AfterThrowing(pointcut = "loggingPointcut()", throwing = "e")  public void logAfterThrowing(JoinPoint joinPoint, Throwable e) {    if (env.acceptsProfiles(Constants.SPRING_PROFILE_DEVELOPMENT)) {      log.error("Exception in {}.{}() with cause = \'{}\' and exception = \'{}\'",        joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName(),        e.getCause() != null ? e.getCause() : "NULL", e.getMessage(), e);    } else {      log.error("Exception in {}.{}() with cause = {}",        joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName(),        e.getCause() != null ? e.getCause() : "NULL");    }  }  /**   * Advice that logs when a method is entered and exited.   */  @Around("loggingPointcut()")  public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {    ServletRequestAttributes attributes =      (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();    HttpServletRequest request = attributes.getRequest();    // 获取ip    String ip = LogUtil.getIpAddress(request);    // 获取请求头与操作路径    String path = request.getHeader("Page-Name");    if (!StringUtils.isBlank(path)) {      try {        path = URLDecoder.decode(path, "UTF-8");      } catch (UnsupportedEncodingException e1) {        e1.printStackTrace();        log.error("解码错误" + e1.getMessage());      }    }    // 获取当前用户名    String username = UserUtil.getUser().getUsername();    String area = LogUtil.sqlArea(UserUtil.getUser().getArea());    // 通过反射获取方法    String classType = joinPoint.getTarget().getClass().getName();    Class<?> clazz = Class.forName(classType);    String clazzName = clazz.getName();    Signature signature = joinPoint.getSignature();    MethodSignature methodSignature = (MethodSignature) signature;    Method targetMethod = methodSignature.getMethod();    Method realMethod = joinPoint.getTarget().getClass()      .getDeclaredMethod(joinPoint.getSignature().getName(), targetMethod.getParameterTypes());    String methodName = joinPoint.getSignature().getName(); // 获取方法名称    Object[] args = joinPoint.getArgs();    Map<String, Object> nameAndArgs = getFieldsName(this.getClass(), clazzName, methodName, args); // 获取参数名称和值    try {      if (!realMethod.isAnnotationPresent(ApiOperation.class)) {        return 1;      }      // 将map转换为json      String json = mapper.writeValueAsString(nameAndArgs);      // 获取操作内容      ApiOperation apiOperation = realMethod.getAnnotation(ApiOperation.class);      String apiOperationString = apiOperation.value();      boolean isGet = realMethod.isAnnotationPresent(GetMapping.class);      // 判断是否存在 AuditLog 注解      if (realMethod.isAnnotationPresent(AuditLog.class)) {        AuditLog auditLog = realMethod.getAnnotation(AuditLog.class);        boolean skipFlag = auditLog.skip();        joinDatabase(skipFlag, area, username, ip, path, apiOperationString, json);      } else {        // 判断是否 get 请求,以及是否强制打印        joinDatabase(!isGet || !logFlag, area, username, ip, path, apiOperationString, json);      }    } catch (Exception e) {      log.error(e.getMessage());    }    return doNext(joinPoint);  }  private Object doNext(ProceedingJoinPoint joinPoint) throws Throwable {    try {      Object result = joinPoint.proceed();      if (log.isDebugEnabled()) {        log.debug("Exit: {}.{}() with result = {}", joinPoint.getSignature().getDeclaringTypeName(),          joinPoint.getSignature().getName(), result);      }      return result;    } catch (IllegalArgumentException e) {      log.error("Illegal argument: {} in {}.{}()", Arrays.toString(joinPoint.getArgs()),        joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());      throw e;    }  }  /**   * 记录插入数据库   */  private void joinDatabase(boolean flag, String area, String username, String ip, String path,                            String apiOperationString, String json) {    if (flag) {      loggingService.addLogging(area, username, ip, path, apiOperationString, json);      log.debug("插入数据库成功  " + " 区域:" + area + " 用户名:" + username + " ip地址: " + ip + " 操作路径: " + path + " ,操作:"        + apiOperationString + ", 参数为:" + json + ", 操作时间为:" + new Date());    } else {      log.debug(" 区域:" + area + " 用户名:" + username + " ip地址: " + ip + " 操作路径: " + path + " ,操作:" + apiOperationString        + ", 参数为:" + json + ", 操作时间为:" + new Date());    }  }  //全部参数转换为map  private Map<String, Object> getFieldsName(Class cls, String clazzName, String methodName,                                            Object[] args) throws NotFoundException {    if (args == null || args.length <= 0) return null;    Map<String, Object> map = new HashMap<>();    ClassPool pool = ClassPool.getDefault();    // ClassClassPath classPath = new ClassClassPath(this.getClass());    ClassClassPath classPath = new ClassClassPath(cls);    pool.insertClassPath(classPath);    CtClass cc = pool.get(clazzName);    CtMethod cm = cc.getDeclaredMethod(methodName);    org.apache.ibatis.javassist.bytecode.MethodInfo methodInfo = cm.getMethodInfo();    CodeAttribute codeAttribute = methodInfo.getCodeAttribute();    LocalVariableAttribute attr =      (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);    if (attr != null) {      // String[] paramNames = new String[cm.getParameterTypes().length];      int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;      for (int i = 0; i < cm.getParameterTypes().length; i++) {        if (args[i] == null) {          map.put(attr.variableName(i + pos), "");          continue;        }        String argsStr = args[i].toString();        try {          if (argsStr.getBytes("UTF-8").length < 3000) {            map.put(attr.variableName(i + pos), args[i]);// paramNames即参数名          } else {            String[] msg = StringCutUtil.cutByteByUTF8(args[i].toString(), 512);            map.put(attr.variableName(i + pos), msg[0]);            log.debug("超级长的参数{},时间是{}", args[i], new Date());          }        } catch (UnsupportedEncodingException e) {          e.printStackTrace();        }      }    }    // Map<>    return map;  }}
原创粉丝点击