springboot springmvc拦截器 拦截POST、PUT、DELETE请求参数和响应数据,并记录操作日志详解编程语言

1.操作日志实体类

@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.拦截器

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(); 
  } 
}

测试结果:

springboot springmvc拦截器 拦截POST、PUT、DELETE请求参数和响应数据,并记录操作日志详解编程语言

 

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/16942.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论