为什么从HttpRequest拿出数据需要重写getInputStream方法

本文详细分析了在SpringMVC框架下,为什么不能在Controller层之前从HttpRequest的输入流中读取数据,原因是CoyoteInputStream不支持reset()方法,导致数据只能读取一次。解决方案是重写getInputStream方法,每次返回新的InputStream对象,确保数据能被正确处理。此外,文章还探讨了流的关闭和管理,指出并非所有流都需要手动关闭,但大型项目中手动回收仍有价值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

很多文章解释这个问题的是,说是SpringMVC自己用的InputStream没有实现reset()方法,而JDK大部分自带InputStream实现了这个方法,所以可以让InputStream重复读取,但是在笔者仔细了解后,发现实质上不是reset()的问题。

背景

在进行为公司开发接口验签,想在controller前就拿到数据进行验签时,出现了到达controller拿到的body为空的问题,网络上大部分文章千篇一律,都说了是InputStream的read方法只能读取一次的问题,在笔者debug后,逐层分析,写下这篇文章。

分析过程

1. 在进入controller层前拿出输入流的问题

因为SpringMVC框架中,最后是由DispatcherServlet进行请求分发,再走到相应的RequestMapping对应的方法,所以在filter中拿出数据,就能模拟出controller前拿出数据的方法。
首先写一个Filter,并在启动类上配置@ServletComponentScan注解扫描servlet系列组件

/**
 * @author kiring
 * @date 2020/3/1 1:11
 */
@WebFilter(urlPatterns = "/*")
public class RequestBufferedFilter implements Filter {
   
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
   

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
   
        if(servletRequest instanceof HttpServletRequest){
   
            byte[] bytes = new byte[1024];
            // InputStream被封装进request中,所以我们也要从request拿到这个inputstream
            servletRequest.getInputStream().read(bytes);
            System.out.println(new String(bytes,"utf-8"));
            filterChain.doFilter("过滤器拿到请求数据:" + servletRequest,servletResponse);
        }
    }

    @Override
    public void destroy() {
   

    }
}

当我们调用POST请求时,(为什么是POST请求,因为除了文件传输等请求,POST的requestBody数据是以InputStream进行传输的,其他数据可以从url上拿到并封装在request中,通过POST请求可以验证inputstream拿出数据的结果)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值