统一日志输出打印POST请求参数
众所周知,request.getInputStream()只能调一次。如果希望在请求进入Controller之前统一打印请求参数(拦截器或过滤器),又不影响业务,我们只能将获取到的输入流缓存起来,后续都从缓存中获取即可。
首先,自定义一个ServletInputStream
package com.cjs.example.log.filter;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
/**
* @Author: ChengJianSheng
* @Date: 2023/3/6
*/
public class CustomServletInputStream extends ServletInputStream {
private ByteArrayInputStream inputStream;
public CustomServletInputStream(byte[] body) {
this.inputStream = new ByteArrayInputStream(body);
}
@Override
public boolean isFinished() {
return inputStream.available() == 0;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() throws IOException {
return inputStream.read();
}
}
然后,自定义一个HttpServletRequestWrapper
package com.cjs.example.log.filter;
import org.apache.commons.io.IOUtils;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
/**
* @Author: ChengJianSheng
* @Date: 2023/3/6
*/
public class CustomHttpServletRequestWrapper extends HttpServletRequestWrapper {
private byte[] body;
public CustomHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
body = IOUtils.toByteArray(request.getInputStream());
}
@Override
public ServletInputStream getInputStream() throws IOException {
return new CustomServletInputStream(body);
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream(), getCharacterEncoding()));
}
}
接下来,写一个过滤器,在过滤器中打印请求参数
package com.cjs.example.log.filter;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* @Author: ChengJianSheng
* @Date: 2023/3/6
*/
public class LogFilter implements Filter {
private final static Logger logger = LoggerFactory.getLogger(LogFilter.class);
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
CustomHttpServletRequestWrapper requestWrapper = new CustomHttpServletRequestWrapper((HttpServletRequest) servletRequest);
printLog(requestWrapper);
filterChain.doFilter(requestWrapper, servletResponse);
}
private void printLog(CustomHttpServletRequestWrapper requestWrapper) throws IOException {
logger.info("请求URL: {}", requestWrapper.getRequestURL());
String method = requestWrapper.getMethod();
if ("GET".equalsIgnoreCase(method)) {
logger.info("请求参数: {}", requestWrapper.getQueryString());
} else if ("POST".equalsIgnoreCase(method) && "application/json".equalsIgnoreCase(requestWrapper.getContentType())) {
String body = IOUtils.toString(requestWrapper.getInputStream(), requestWrapper.getCharacterEncoding());
logger.info("请求参数: {}", body);
}
}
}
请求经过过滤器的时候,首先在构造CustomHttpServletRequestWrapper的时候将请求中的InputStream转成字节数字缓存到内存中,然后后面每次再getInputStream()的时候都从缓存中取出内容并返回一个新的ServletInputStream
最后,定义一个配置类
package com.cjs.example.log.config;
import com.cjs.example.log.filter.LogFilter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Author: ChengJianSheng
* @Date: 2023/3/6
*/
@Configuration
public class CustomLogAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public LogFilter logFilter() {
return new LogFilter();
}
}
在resources/META-INF/spring.factories中新增一行自动配置
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.cjs.example.log.config.CustomLogAutoConfiguration
统一日志输出打印POST请求参数的更多相关文章
- Logback 整合 RabbitMQ 实现统一日志输出
原文地址:Logback 整合 RabbitMQ 实现统一日志输出 博客地址:http://www.extlight.com 一.前言 公司项目做了集群实现请求分流,由于线上或多或少会出现请求失败或系 ...
- Spring AOP实现统一日志输出
目的: 统一日志输出格式 思路: 1.针对不同的调用场景定义不同的注解,目前想的是接口层和服务层. 2.我设想的接口层和服务层的区别在于: (1)接口层可以打印客户端IP,而服务层不需要 (2)接口层 ...
- nginx 日志打印post请求参数
在日志格式后面加上 $request_body 配置信息 log_format main '$remote_addr - $remote_user [$time_local] "$reque ...
- 转发:tomcat的acess_log打印post请求参数,分析日志
转载自:https://blog.csdn.net/qq_30121245/article/details/52861935 1) 在项目中加入相应的包和类,加载那里无所谓,只要web.xml配置正确 ...
- spring Aop切面中的@Before @Around等执行顺序与请求参数统一解码
1.背景 在实际开发中,我可能会对请求接口做统一日志输出,或者统一参数解析,验签,统一响应加密等,通常会用到aop,实际案例如下 2.代码 package com.qianxingniwo.log; ...
- SpringBoot2.0针对请求参数@RequestBody验证统一拦截
title: "SpringBoot2.0针对请求参数@RequestBody验证的统一拦截"categories: SpringBoot2.0 Shirotags: Spring ...
- springboot 学习之路 4(日志输出)
目录:[持续更新.....] spring 部分常用注解 spring boot 学习之路1(简单入门) spring boot 学习之路2(注解介绍) spring boot 学习之路3( 集成my ...
- Spring AOP统一日志 全量日志
Spring AOP 切面@Around注解的具体使用 lichuangcsdn 2019-02-19 23:21:36 63936 收藏 61分类专栏: Spring 文章标签: Spring AO ...
- struts2之请求参数接收
struts2之请求参数接收 1. 采用基本类型接受请求参数(get/post)在Action类中定义与请求参数同名的属性,struts2便能自动接收请求参数并赋予给同名的属性.请求路径:http:/ ...
- struts2接受请求参数
https://blog.csdn.net/y249839817/article/details/77702745 https://blog.csdn.net/nthack5730/article/d ...
随机推荐
- ONVIF网络摄像头(IPC)客户端开发—ONVIF介绍
1.前言: 网上已经有很多关于ONVIF开发的资料,这里概括介绍一下ONVIF协议以及介绍一下我自己在开发ONVIF网络摄像头的一些流程和经验,做个开发记录和经验总结,以备将来查看,也可供他人参考 ...
- canal报错nosuchmethod ..bytebuffer
解决方法:更新jdk版本与es一致
- [转帖]linux下查看内存频率,内核函数,cpu频率
https://www.cnblogs.com/lovesKey/p/10900501.html 查看CPU: cat /proc/cpuinfo # 总核数 = 物理CPU个数 X 每颗物理CPU的 ...
- Cloudquery的学习安装与使用
Cloudquery的学习安装与使用 下载 官方下载地址: https://www.cloudquery.club/download https://pan.baidu.com/s/1a7XOrnMU ...
- blackbox的简单学习-监控web服务是否正常以及证书过期时间
blackbox的简单学习-监控web服务是否正常以及证书过期时间 下载blackbox https://github.com/prometheus/blackbox_exporter 可以在rele ...
- [转帖]麒麟v10上部署TiDBv5.1.2生产环境的最佳实践
https://tidb.net/book/tidb-monthly/2022/2022-07/usercase/tidb-v5-1-2 前言 笔者最近在一个银行项目中做 PoC 测试,由于客户选择 ...
- [转帖]arm linux下编译xtrabackup-2.4.5
环境:aarch64/centos7.6 glibc-2.17 编译器:gcc version 5.5.0 (GCC) 官方参考文档:https://www.percona.com/doc/perc ...
- [转贴]汉字编码:GB2312, GBK, GB18030, Big5
汉字编码:GB2312, GBK, GB18030, Big5 https://www.cnblogs.com/malecrab/p/5300497.html 前一篇博文:ANSI是什么编码?中有这样 ...
- java 调优需要关闭的组建
- 学习: Linux的 date 命令
date 命令非常好用 多用 date --h 还是非常好的 获取 今天是今年的第多少天 最简单的办法 就是 date +%j 以后需要多学习 多利用 linux的帮助才可以呢. Usage: dat ...