springboot springmvc攔截器 攔截POST、PUT、DELETE請求參數和響應數據,並記錄操做日誌

1.操做日誌實體類java

@Document(collection = "operation_log")
@Getter
@Setter
@ToString
public class OperationLog extends BaseEntityWithId {
  private String userId; // 操做人
  private String resource; // 操做的資源
  private String requestMethod; // 請求方式
  private String beanName; // 操做的類
  private String methodName; // 操做的模塊
  private String requestParams; // 請求的參數
  private String responseData; // 返回數據
}

2.攔截器web

package com.vian.admin.config;

import com.alibaba.fastjson.JSON;
import com.vian.admin.entity.OperationLog;
import com.vian.admin.event.OperationLogEvent;
import com.vian.core.configuration.event.EventPublisher;
import com.vian.microservice.security.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;


@Aspect
@Component
@Slf4j
public class RequestLogAspect {
  @Autowired private EventPublisher eventPublisher;
  private ThreadLocal<OperationLog> logThreadLocal = new ThreadLocal<>();
  //攔截web下全部方法
  @Pointcut("execution(* com.vian.admin.web..*.*(..))")
  public void pointcut() {
    log.info("攔截請求start");
  }

  @Before("pointcut()")
  public void doBefore(JoinPoint joinPoint) {

    ServletRequestAttributes attributes =
        (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    HttpServletRequest request = attributes.getRequest();
    String beanName = joinPoint.getSignature().getDeclaringTypeName();
    String methodName = joinPoint.getSignature().getName();
    String uri = request.getRequestURI();
    String userId = SecurityUtils.getCurrentUserId();
    //get方法不記錄日誌
    if ("GET".equals(request.getMethod())) {
      return;
    }
    //請求參數
    Object[] paramsArray = joinPoint.getArgs();
    log.info(
        "請求日誌攔截:userId={}, uri={}, method={}, request={}",
        userId,
        uri,
        request.getMethod(),
        paramsArray);
    // 組裝日誌數據
    OperationLog optLog = new OperationLog();
    optLog.setUserId(userId);
    optLog.setResource(uri);
    optLog.setRequestMethod(request.getMethod());
    optLog.setBeanName(beanName);
    optLog.setMethodName(methodName);
    optLog.setRequestParams(argsArrayToString(paramsArray));
    logThreadLocal.set(optLog);
  }

  @AfterReturning(returning = "result", pointcut = "pointcut()")
  public void doAfterReturning(Object result) {
    try {
      // 處理完請求,從線程變量中獲取日誌數據,並記錄到db
      OperationLog optLog = logThreadLocal.get();
      if (null != optLog) {
        optLog.setResponseData(JSON.toJSONString(result));
        eventPublisher.publish(new OperationLogEvent(this, optLog));
      }
    } catch (Exception e) {
      log.error("***操做請求日誌記錄失敗doAfterReturning()***", e);
    } finally {
      // 清除threadlocal
      logThreadLocal.remove();
    }
  }

  /**
   * 請求參數拼裝
   *
   * @param paramsArray
   * @return
   */
  private String argsArrayToString(Object[] paramsArray) {
    String params = "";
    if (paramsArray != null && paramsArray.length > 0) {
      for (int i = 0; i < paramsArray.length; i++) {
        Object jsonObj = JSON.toJSON(paramsArray[i]);
        params += jsonObj.toString() + " ";
      }
    }
    return params.trim();
  }
}

測試結果:spring

相關文章
相關標籤/搜索