统一日志输出打印POST请求参数
Posted 狂乱的贵公子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了统一日志输出打印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请求参数的主要内容,如果未能解决你的问题,请参考以下文章