首页 > 其他分享 >统一日志输出打印POST请求参数

统一日志输出打印POST请求参数

时间:2023-03-06 18:45:47浏览次数:38  
标签:打印 public IOException requestWrapper org import POST servlet 日志

众所周知,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

 

标签:打印,public,IOException,requestWrapper,org,import,POST,servlet,日志
From: https://www.cnblogs.com/cjsblog/p/17184909.html

相关文章

  • postgreSQL 查询表结构
    SELECTDISTINCTC.relnameAStabname,obj_description(C.oid)ASCOMMENTFROM(SELECTDISTINCTtablename,schemanameFROMpg_tablesWHEREPOSITION('_2'IN......
  • 怎么打印飞书的审批单?
    飞书是字节跳动于2016年自研的新一代一站式协作平台,是保障字节跳动全球数万人高效协作的办公工具。飞书将即时沟通、日历、云文档、云盘和工作台深度整合,通过开放兼容的平......
  • 银河麒麟v10 sp1 安装 PostgreSQL 11.16
    一、安装环境   操作系统:银河麒麟v10 sp3 x86_64   内核版本:   PostgreSQL版本:11.16二、安装过程2.1下载源码包创建目录mkdir-p/tools/postgresql......
  • 安卓NDK本地开发中使用logcat打印日志
    配置在需要打印日志的文件中添加以下头文件和宏定义#include<android/log.h>#defineLOGD(...)__android_log_print(ANDROID_LOG_INFO,"LOG_TAG",__VA_ARGS__)#de......
  • Dynamics CRM是否记录有某个用户大量下载记录的日志?
    DynamicsCRM是否记录有某个用户大量下载记录的日志?比如查看某个用户在客户实体或联系人实体上通过"导出至Excel"导出了大量数据。这个功能由Office365的审核提供,但是......
  • SQL Server20 数据库 减少日志
      解决方案1-直接删除本地ldf日志文件:(比较靠谱方案!)  1.在SQL管理器分离数据库。 2.对数据库日志文件进行压缩备份(rar,zip) 3.直接删除ldf文件。 4.......
  • PostgreSQL技术大讲堂 - Part 9:pg_hba.conf配置
     PostgreSQL从小白到专家,是从入门逐渐能力提升的一个系列教程,内容包括对PG基础的认知、包括安装使用、包括角色权限、包括维护管理、、等内容,希望对热爱PG、学习PG的同......
  • 【java】log日志体系学习
    logback配置详解(一)——logger、root:https://www.cnblogs.com/cb0327/p/5759441.htmlSLF4J(二)-SLF4J绑定了多个实现类的错误是怎么一回事儿?源码解析https://blog.c......
  • 好文章!收藏了!————JS学习日志18 -- JS基础--对象引用和复制
                  参考:https://blog.csdn.net/Android_boom/article/details/125099640......
  • smartctl查看错误日志失败
    1.问题ErrorCounterloggingnotsupportedDevicedoesnotsupportSelfTestlogging#smartctl-lerror-lselftest/dev/sdbsmartctl7.32022-02-28r5338......