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请求参数和响应数据,并记录操作日志的更多相关文章

  1. 防止SpringMVC拦截器拦截js等静态资源文件

    SpringMVC提供<mvc:resources>来设置静态资源,但是增加该设置如果采用通配符的方式增加拦截器的话仍然会被拦截器拦截,可采用如下方案进行解决: 方案一.拦截器中增加针对静 ...

  2. Springboot前后端分离中,后端拦截器拦截后,前端没有对应的返回码可以判断

    项目登录流程如下 用户进入前端登录界面,输入账号密码等,输入完成之后前端发送请求到后端(拦截器不会拦截登录请求),后端验证账号密码等成功之后生成Token并存储到数据库,数据库中包含该Token过期时 ...

  3. Springboot通过拦截器拦截请求信息收集到日志

    1.需求 最近在工作中遇到的一个需求,将请求中的客户端类型.操作系统类型.ip.port.请求方式.URI以及请求参数值收集到日志中,网上找资料说用拦截器拦截所有请求然后收集信息,于是就开始了操作: ...

  4. Struts2 拦截器—拦截action

    对于拦截器的基本使用这里我就懒得打字了,我这里就讲下如何用 Struts2 拦截器 拦截action.这是我个人的想法,如果有什么不对的,或者你们有什么更好的方法.请多多留言! 拦截器的默认拦截的方法 ...

  5. java端拦截器判断客户的的请求是否是ajax请求

    java端拦截器判断客户的的请求是否是ajax请求 发表于 2014-08-22 23:38:08 普通请求与ajax请求的报文头不一样,通过如下 String requestType = reque ...

  6. SpringMVC请求参数和响应结果全局加密和解密

    前提 前段时间在做一个对外的网关项目,涉及到加密和解密模块,这里详细分析解决方案和适用的场景.为了模拟真实的交互场景,先定制一下整个交互流程.第三方传输(包括请求和响应)数据报文包括三个部分: 1.t ...

  7. 使用SpringBoot AOP 记录操作日志、异常日志

    平时我们在做项目时经常需要对一些重要功能操作记录日志,方便以后跟踪是谁在操作此功能:我们在操作某些功能时也有可能会发生异常,但是每次发生异常要定位原因我们都要到服务器去查询日志才能找到,而且也不能对发 ...

  8. 扩展SpringMVC以支持绑定JSON格式的请求参数

    此方案是把请求参数(JSON字符串)绑定到java对象,,@RequestBody是绑定内容体到java对象的. 问题描述: <span style="font-size: x-sma ...

  9. 在JSP中常见问题,防止SpringMVC拦截器拦截js等静态资源文件的解决方案

    方案一.拦截器中增加针对静态资源不进行过滤(涉及spring-mvc.xml) <mvc:resources location="/" mapping="/**/* ...

随机推荐

  1. Swift中的for循环基本使用

    OC中的for循环写法: ;i < ;i++) { NSLog(@"i=%zd",i); } Swift中的for循环写法: let a = ; ..< a { pri ...

  2. Python入门测试

    1.比如自然数10以下能被3或者5整除的有,3,5,6和9,那么这些数字的和为23. 求能被3或者5整除的1000以内数字的和 multiple_of_threes=[] for multiple_o ...

  3. ARTS打卡第三周

    Algorithm 题目描述 Given an array of integers, find if the array contains any duplicates. Your function ...

  4. 小程序--scroll-view的横向滑动无效

  5. 001_Go hello world

    一.go获取程序参数及指针地址示例 package main import ( "fmt" "os" ) func main() { fmt.Println(o ...

  6. 如何使用ASP.NET Core、EF Core、ABP(ASP.NET Boilerplate)创建分层的Web应用程序(第一部分)

    本文是为了学习ABP的使用,是翻译ABP官方文档的一篇实战教程,我暂时是优先翻译自己感兴趣或者比较想学习的部分,后续有时间希望能将ABP系列翻译出来,除了自己能学习外,有可能的话希望帮助一些英文阅读能 ...

  7. day11(函数参数,函数对象,打散机制,函数嵌套调用)

    一,复习 # 什么是函数:具体特定功能的代码块 - 特定功能代码块作为一个整体,并给该整体命名,就是函数 # 函数的优点: # 1.减少代码的冗余 # 2.结构清晰,可读性强 # 3.具有复用性,开发 ...

  8. WebSocket群聊与单聊

    一 . WebSocket实现群聊 py文件代码 # py文件 from flask import Flask, render_template, request from geventwebsock ...

  9. <generatePublisherEvidence> 元素

    <configuration> <runtime> <generatePublisherEvidence enabled="false"/> & ...

  10. Linux学习之路1

    root用户 安装初始系统默认没有启动root用户,如下方式启动: l  sudo passwd l  连续输入两次密码,启动root用户 l  再登陆 登陆root用户 l  su root l  ...