springboot在使用 Servlet API中提供的javax.servlet.Filter 过滤器 对请求参数 和 响应参数 进行获取并记录日志方案

不多说 直接上代码
第一步

package com.xxx.init.webFilter;import com.alibaba.fastjson.JSONObject;
import com.xxx.api.constant.CommonConstant;
import com.xxx.api.entities.log.OperationLog;
import com.xxx.init.utils.JwtHelper;
import com.xxx.init.utils.RequestUtils;
import com.xxx.init.utils.WlUtils;
import com.xxx.init.webFilter.jsonWrapper.JsonParameterRequestWrapper;import com.xxx.init.webFilter.jsonWrapper.ResponseWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;/*** User:Json* Date: 2024/4/3* 日志操作**/
@WebFilter(urlPatterns = {"/*"}, filterName = "OperationLogFilter")
@Order(-100)
@Slf4j
public class OperationLogFilter implements Filter {@Value("${spring.application.name}")private String serviceName;@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {HttpServletRequest httpServletRequest = (HttpServletRequest) request;HttpServletResponse httpServletResponse = (HttpServletResponse) response;if ("GET".equals(httpServletRequest.getMethod())) {chain.doFilter(request, response);return;}// 在请求到达 Servlet 前执行的逻辑boolean isDownload = false;// 检查响应头信息String contentDescription = httpServletRequest.getHeader("content-description");String contentTransferEncoding = httpServletRequest.getHeader("content-transfer-encoding");if (!StringUtils.isEmpty(contentDescription) &&!StringUtils.isEmpty(contentTransferEncoding)) {isDownload = true; // 设置为 true,表示需要下载}OperationLog operationLog = new OperationLog();operationLog.setOrg_id(0);operationLog.setTime(LocalDateTime.now());operationLog.setMethod(httpServletRequest.getMethod());operationLog.setRouter(httpServletRequest.getRequestURI());operationLog.setProtocol(httpServletRequest.getProtocol());operationLog.setIp(httpServletRequest.getRemoteAddr());operationLog.setService_name(serviceName);//获取请求类型为 Json的 数据 如果是form-data 类型的数据 目前没获取JsonParameterRequestWrapper jsonParameterRequestWrapper = null;if (WlUtils.isJsonReq(httpServletRequest)) {jsonParameterRequestWrapper = new JsonParameterRequestWrapper(httpServletRequest);operationLog.setRequest_data(getRequestJson(jsonParameterRequestWrapper));}ResponseWrapper responseWrapper = new ResponseWrapper(httpServletResponse);if (jsonParameterRequestWrapper == null) {chain.doFilter(request, responseWrapper);} else {chain.doFilter(jsonParameterRequestWrapper, responseWrapper);}String s = new String(responseWrapper.getContent(), "UTF-8");operationLog.setResponse_code(responseWrapper.getStatus());operationLog.setResponse_data(isDownload ? "文件下载" : s);// 在得到响应的数据之后,response的输出流中就无可用的数据,所以需要巴数据放回去ServletOutputStream outputStream = response.getOutputStream();outputStream.write(responseWrapper.getContent());outputStream.flush();outputStream.close();}private JSONObject getRequestJson(JsonParameterRequestWrapper jsonParameterRequestWrapper) throws IOException {String bodyMessage = jsonParameterRequestWrapper.getBodyMessage();JSONObject jsonObject = JSONObject.parseObject(bodyMessage);return jsonObject;}@Overridepublic void destroy() {}
}

第二步:

package com.xxx.init.webFilter.jsonWrapper;import com.xxx.init.utils.StreamUtil;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
/*** User:Json* Date: 2024/4/7**/
public class JsonParameterRequestWrapper extends HttpServletRequestWrapper {//用于保存读取body中数据private  byte[] body;private String bodyMessage;public JsonParameterRequestWrapper(HttpServletRequest request) throws IOException {super(request);//读取请求的数据保存到本类当中body = StreamUtil.readBytes(request.getReader(), "UTF-8");bodyMessage =  new String(body,"utf-8");}//覆盖(重写)父类的方法@Overridepublic BufferedReader getReader() throws IOException {return new BufferedReader(new InputStreamReader(getInputStream()));}//覆盖(重写)父类的方法@Overridepublic ServletInputStream getInputStream() throws IOException {final ByteArrayInputStream bais = new ByteArrayInputStream(body);return new ServletInputStream() {@Overridepublic boolean isFinished() {return false;}@Overridepublic boolean isReady() {return false;}@Overridepublic void setReadListener(ReadListener readListener) {}@Overridepublic int read() throws IOException {return bais.read();}};}/*** 获取body中的数据* @return*/public byte[] getBody() {return body;}/*** 把处理后的参数放到body里面* @param body*/public void setBody(byte[] body) {this.body = body;}public String getBodyMessage() {return bodyMessage;}
}

第三步

package com.xxx.init.webFilter.jsonWrapper;import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.*;
import java.nio.charset.StandardCharsets;/*** User:Json* Date: 2024/4/7**/
public class ResponseWrapper extends HttpServletResponseWrapper {private ByteArrayOutputStream byteArrayOutputStream;private ServletOutputStream servletOutputStream;/*** Constructs a response adaptor wrapping the given response.* @param response The response to be wrapped* @throws IllegalArgumentException if the response is null*/public ResponseWrapper(HttpServletResponse response) throws IOException {super(response);byteArrayOutputStream = new ByteArrayOutputStream();servletOutputStream = new MyServletOutputStream(byteArrayOutputStream);}@Overridepublic ServletOutputStream getOutputStream() throws IOException {return servletOutputStream;}@Overridepublic PrintWriter getWriter() throws IOException {return new PrintWriter(new OutputStreamWriter(byteArrayOutputStream, StandardCharsets.UTF_8));}@Overridepublic void flushBuffer() {if (servletOutputStream != null) {try {servletOutputStream.flush();} catch (IOException e) {e.printStackTrace();}}}public byte[] getContent() {flushBuffer();// response中的数据return byteArrayOutputStream.toByteArray();}class MyServletOutputStream extends ServletOutputStream {// 把response输出流中的数据写入字节流中private ByteArrayOutputStream byteArrayOutputStream;public MyServletOutputStream(ByteArrayOutputStream byteArrayOutputStream) {this.byteArrayOutputStream = byteArrayOutputStream;}@Overridepublic boolean isReady() {return false;}@Overridepublic void setWriteListener(WriteListener listener) {}@Overridepublic void write(int b) throws IOException {byteArrayOutputStream.write(b);}}
}

第五步:

package com.xxx.init.utils;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/*** User:Json* Date: 2024/4/7**/
public class StreamUtil {public static byte[] readStream(InputStream stream,int length) throws IOException {byte[]streamData=null;List<Integer> lengths = new ArrayList<Integer>();List<byte[]> buffers = new ArrayList<byte[]>();int l = 0;  int totalLength = 0;  byte[] buffer = null; //while (totalLength < length && l != -1) { //buffer = new byte[length];l = stream.read(buffer);if (l != -1) {lengths.add(new Integer(l));buffers.add(buffer);totalLength+=l;}}if(totalLength==0) {return null;}l=0;streamData = new byte[totalLength];length =buffers.size();int blength=0;byte[] bbuffer=null;for (int i = 0; i < length; i++) {blength = ((Integer) lengths.get(i)).intValue();bbuffer = (byte[]) buffers.get(i);System.arraycopy(bbuffer, 0, streamData, l,blength);l=l+blength;}stream=null; lengths=null; buffers=null;	buffer=null;return streamData;}public static byte[] readBytes(BufferedReader bufferedReader, String charset) throws IOException{StringBuffer sb = new StringBuffer();String s;while ((s = bufferedReader.readLine()) != null) {sb.append(s);}if(sb.length() == 0){return "".getBytes(charset);}return sb.toString().getBytes(charset);}}

第六步:

package com.xxx.init.utils;import javax.servlet.http.HttpServletRequest;/*** User:Json* Date: 2024/4/7**/
public class WlUtils {/*** 判断是否是JSON请求* @param request* @return*/public static Boolean isJsonReq(HttpServletRequest request){String header = request.getHeader("content-type");return header != null && header.toLowerCase().contains("json");}
}

测试
在这里插入图片描述
完美收工

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/808517.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c++和java中常用语法对照

1.vector c #include<vector> std::vector<>a;//创建 a[i]//访问,获取 a[i]v;//修改 a.push_back(v)//添加元素 a.erase(a.beginw-1)//删除第w个元素 std::sort(a.begin,a.end); std::reverse(a.begin(),a.end());java import java.util.Vector; Vector<Inte…

antd+Vue 3实现table行内upload文件图片上传【超详细图解】

目录 一、背景 二、效果图 三、代码 一、背景 一名被组长逼着干前端的苦逼后端&#xff0c;在一个晴天霹雳的日子&#xff0c;被要求前端订单产品实现上传产品图片并立刻回显图片。 二、效果图 三、代码 <template><a-table :dataSource"dataSource" :c…

如何使用固定公网地址SSH远程访问本地内网openEuler系统

文章目录 1. 本地SSH连接测试2. openEuler安装Cpolar3. 配置 SSH公网地址4. 公网远程SSH连接5. 固定连接SSH公网地址6. SSH固定地址连接测试 欧拉操作系统(openEuler, 简称“欧拉”)是面向数字基础设施的操作系统,支持服务器、云计算、边缘openEuler是面向数字基础设施的操作系…

javaScript Object.hasOwn()的用法

Object.hasOwn() 如果指定的对象自身有指定的属性&#xff0c;则静态方法 Object.hasOwn() 返回 true。如果属性是继承的或者不存在&#xff0c;该方法返回 false。 备注&#xff1a; Object.hasOwn() 旨在取代 Object.prototype.hasOwnProperty()。 **语法&#xff1a;**Objec…

洛谷 P1434滑雪

[SHOI2002] 滑雪 题目描述 Michael 喜欢滑雪。这并不奇怪&#xff0c;因为滑雪的确很刺激。可是为了获得速度&#xff0c;滑的区域必须向下倾斜&#xff0c;而且当你滑到坡底&#xff0c;你不得不再次走上坡或者等待升降机来载你。Michael 想知道在一个区域中最长的滑坡。区域…

【图论】Dijkstra单源最短路径-朴素方法-简单模板(迪杰斯特拉算法)

Dijkstra单源最短路径 问题描述 输入n 表示n个结点&#xff0c;m表示m条边&#xff0c;求编号1的结点到每个点的最短路径 输出从第一个点到第n个点的最短路径 思路 将图g[][]中所有的权值初始化为0x3f表示正无穷 将dist[]中所有的值初始化为0x3f表示从第一个点到所有点的距离…

NX/UG二次开发—CAM—一些外挂刀路选择方案对比

在做一刀轨编辑工具时&#xff0c;大家希望实现类似NX刀轨编辑中选择刀路的功能&#xff0c;以下我罗列了几种目前外挂里使用的几种方式&#xff0c;自己也做了一些对比&#xff1a; 涉及一些运算时间&#xff0c;参考电脑配置(内存32G&#xff0c;CPUi9-12950HX) 1、刀路转成…

PCB封装库的创建及引入

法1 1.创建lib 2.放置 找到你想要画的封装的器件的数据手册了解相关信息。 直插式选Multi-layer 贴片选Top-layer 焊盘尺寸 焊盘空尺寸 法2 嘉立创eda直接copy 再嘉立创中找到你想要的pcb&#xff0c;导出为ad 然后再ad中找到我们导出的文件 复制他 然后再库中粘贴 pcb库…

sky光遇加速器推荐 steam光遇低延迟稳定的加速器推荐

在光遇游戏中&#xff0c;子民指的就是游戏中的人影&#xff0c;玩家在游戏里面需要找到蓝色人影并触碰它&#xff0c;然后跟随光点&#xff0c;这样的话我们就可以看到一个深灰色的石像&#xff0c;点燃石像上的火苗&#xff0c;它就会教我们一个新的互动姿势。玩家找到黄色人…

Python中Python-docx 包的run介绍

先对run做一个简单地介绍。每个paragraph对象都包含一个run对象的列表。举例&#xff1a; 这是一个简短的段落。 from docx import Document doc Document("1.docx") #上面这段话保存在1.docx中 print("这一段的run个数是&#xff1a;",len(doc.paragr…

C语言—每日选择题—Day70(需要看)

第一题&#xff08;注&#xff09; 1、关于内存管理&#xff0c;以下有误的是&#xff08; &#xff09; A: malloc在分配内存空间大小的时候是以字节为单位 B: 如果原有空间地址后面还有足够的空闲空间用来分配&#xff0c;则在原有空间后直接增加新的空间&#xff0c;使得增加…

《一》Qt的概述

1.1 什么是Qt Qt是一个跨平台的C图形用户界面应用程序框架。它为应用程序开发者提供建立图形界面所需的所有功能。它是完全面向对象的&#xff0c;很容易扩展&#xff0c;并且允许真正的组件编程。 1.2 Qt的发展史 1991年 Qt最早由芬兰奇趣科技开发 1996年 进入商业领域&#x…

未来课堂革命:OpenAI 发布 ChatGPT 使用指南,探索生成式 AI 如何重塑教育景观

随着新学期的来临&#xff0c;众多初登教师舞台的 00 后们&#xff0c;也完成了他们的第一个教师身份下的暑期生活。 对于开学的抵触情绪&#xff0c;不仅学生们普遍存在&#xff0c;许多 00 后的新晋教师们也同样感同身受。某种程度上&#xff0c;这些抗拒上班的年轻教师群体…

Go-学会 Go 中 interface 的基本使用

本节重点&#xff1a; 学会 Go 中 interface 的基本使用 在 Go 中&#xff0c;接口类型是一种抽象类型&#xff0c;是方法的集合&#xff0c;其他类型实现了这些方法就是实现了这个接口。 声明和实现接口 在 Go 中接口的声明如下&#xff1a; /* 定义接口 */ type interface…

Mac上的最佳3D建模工具-犀牛Rhinoceros 8 for Mac v8.6.24101.05002完美兼容激活

Rhino 8是一款计算机辅助设计&#xff08;CAD&#xff09;和三维建模软件&#xff0c;由美国公司McNeel & Associates开发。它是Rhino系列的最新版本&#xff0c;用于创建、编辑、分析、渲染和动画三维模型。 以下是Rhino 8的一些主要特点和功能&#xff1a; 1. **强大的…

Spring Boot与Vue联手打造智能化学生选课平台

末尾获取源码作者介绍&#xff1a;大厂全栈码农|毕设实战开发&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。 更多项目&#xff1a;CSDN主页YAML墨韵 学如逆水行舟&#xff0c;不进则退。学习如赶路&#xff0c;不能慢一步。 目录 一、项目简介 二、开发技术与…

Scaffold-GS 代码阅读笔记

1. 系统启动部分 使用 python 中的 parser 库 为配置系统的参数设定, 和3DGS 类似&#xff0c;并且使用safe_state(args.quiet) 函数 为每一次的 log 输出加上对应的 时间戳 ## 配置参数的设定lp ModelParams(parser)op OptimizationParams(parser)pp PipelineParams(pars…

分布式向量数据库-安装部署

下载 GitHub - pgvector/pgvector: Open-source vector similarity search for Postgres 源码编译 ##文件解压缩 unzip pgvector-0.6.2.zip ##编译 make && make install 功能验证 #安装扩展CREATE EXTENSION vector;#创建测试表CREATE TABLE items (id bigseri…

TPCH 工具dbgen的安装与使用

最近需要测试MySQL 数据库的tpc-h性能&#xff0c;记录下 下载工具包 在TPC-H Homepage 这个网站下载TCPH的zip包&#xff0c;需要填信息&#xff08;这里有时需要科技网&#xff0c;不然会莫名报错。&#xff09; 编译 dbgen 下载后解压&#xff0c;然后修改 dbgen/makefi…

【算法】哈希表

个人主页 &#xff1a; zxctscl 如有转载请先通知 题目 1. 1. 两数之和1.1 分析1.2 代码 2. 面试题 01.02. 判定是否互为字符重排2.1 分析2.2 代码 3. 217. 存在重复元素3.1 分析3.2 代码 4. 219. 存在重复元素 II4.1 分析4.2 代码 5. 49. 字母异位词分组5.1 分析5.2 代码 1. 1…