在SpringBoot的拦截器中通过流 ( request.getInputStream() ) 的方式读取body中传来的数据会导致controller接收不到值。这个问题其实就是一个流读取的问题众所周知在Java中input流只能读取一次主要原因是通标记的方法来判断流是否读取完毕读取位 -1就是流读取完毕解决这个问题我能想到两种方式通过修改标记的方式 ( inputstream.markSupported() 方法可以判断这个流是否支持 mark 和 reset 方法。他们分别是标记 和 重新定位流。)将流赋值给一个 byte[] 数组或者其他变量保存起来。下载读取流时就调用这个数组就行。第一种方法再回到问题上来我们可以先使用第一种方法判断 requet 中的inputStream 是否支持标记和重新定位。因为这种方式实现起来比较简单。无需考虑太多。OverridepublicbooleanpreHandle(HttpServletRequest request,HttpServletResponse response,Object handler)throwsIOException{booleanbrequest.getInputStream().markSupported();System.out.println(b);}// 输出结果为 false上述代码会返回一个 false 那么很明显request 中的 input 流是不支持标记和重新定位的。第二种方法我们再考虑第二种方法我们需要一个变量保存这个流。并且还要保证再过滤器中和controller中都要拿到这个变量。直接定义一个全局变量获取修改传值方式都是可以的。全局变量这种方式我就不演示了。下面是改变传值方式的 demopublicbooleanpreHandle(HttpServletRequest request,HttpServletResponse response,Object handler)throwsIOException{ServletInputStream inputStream1request.getInputStream();// 各种对 inputStream1 处理的操作...Object obejctinputStream1;request.setAttribute(Params,obejct);}这样就可以再controller那边就可以直接获取 Attribute 中的值。但是这样有很大的局限性例如: 我已经写好了大多数的controller方法体。这时再改用这种方式传值。对于开发人员是一种莫大的痛苦 -_- 于是通过不屑的百度查询到另一种方法 一一一 改写HttpServletRequestWrapper方法。为什么是这个方法因为他实现了 HttpServletRequest 这个接口。也是我们拦截器接收的 request 要求的类型。首先我们先看一张图。**注意 filter 和 inteceptor 中间。**通过上方这个图我们可以知道在 Filter 和 Inteceptor 中间有一层Servlet。而Servlet就是提交request的地方。所以我们要重写HttpServletRequest方法只能在Servlet之前。也就是filter 中。下面就是直接上代码了重写 HttpServletRequestpackagecom.xqw.kyg.util;importjava.io.BufferedReader;importjava.io.ByteArrayInputStream;importjava.io.IOException;importjava.io.InputStreamReader;importjavax.servlet.ReadListener;importjavax.servlet.ServletInputStream;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletRequestWrapper;importorg.springframework.util.StreamUtils;publicclassMyHttpServletRequestWrapperextendsHttpServletRequestWrapper{privatebyte[]requestBodynull;//用于将流保存下来publicMyHttpServletRequestWrapper(HttpServletRequest request)throwsIOException{super(request);requestBodyStreamUtils.copyToByteArray(request.getInputStream());}OverridepublicServletInputStreamgetInputStream(){finalByteArrayInputStream baisnewByteArrayInputStream(requestBody);returnnewServletInputStream(){Overridepublicintread(){returnbais.read();// 读取 requestBody 中的数据}OverridepublicbooleanisFinished(){returnfalse;}OverridepublicbooleanisReady(){returnfalse;}OverridepublicvoidsetReadListener(ReadListener readListener){}};}OverridepublicBufferedReadergetReader()throwsIOException{returnnewBufferedReader(newInputStreamReader(getInputStream()));}}编写Filterpackagecom.xqw.kyg.filter;importcom.xqw.kyg.util.MyHttpServletRequestWrapper;importorg.springframework.stereotype.Component;importjavax.servlet.*;importjavax.servlet.http.HttpServletRequest;importjava.io.IOException;ComponentpublicclassHttpServletRequestReplacedFilterimplementsFilter{Overridepublicvoiddestroy(){}OverridepublicvoiddoFilter(ServletRequest request,ServletResponse response,FilterChain chain)throwsIOException,ServletException{ServletRequest requestWrappernull;if(requestinstanceofHttpServletRequest){requestWrappernewMyHttpServletRequestWrapper((HttpServletRequest)request);}if(requestWrappernull){chain.doFilter(request,response);}else{chain.doFilter(requestWrapper,response);}}Overridepublicvoidinit(FilterConfig arg0)throwsServletException{}}到此代码编写就完成了。你现在可以在 过滤器 中读取inputstream数据controller中也可以获取到了。其实代码并不是特别困难。主要是出现BUG能及时的想到原因和提供解决方案。扩展内容github个人博客