SpringBoot拦截器读取流后不能再读取(详解)
在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个人博客

相关新闻

数据结构实验(C语言):折半查找、哈希查找

数据结构实验(C语言):折半查找、哈希查找

文章参考过网上的内容&#xff0c;如有侵权&#xff0c;请联系 #include<stdio.h> #include<stdlib.h> #define HASHSIZE 12 #define NULLKEY -32768typedef struct {int *elem; //数据元素储存空间基址&#xff0c;建表示按实际长度分配&#xff0c;0号单元留空in…

2026/7/28 16:45:52阅读更多 →
最大连续子串

最大连续子串

问题描述&#xff1a;给定一个由数字组成的数组&#xff0c;求出和最大的子数组求解方法&#xff1a;1.暴力法选取所有连续和的可能性&#xff0c;O(n^2)2.分析法当遍历到第i个元素时&#xff0c;判断在它前面的连续子序列和是否大于0&#xff0c;如果大于0&#xff0c;则以位置…

2026/7/28 16:45:52阅读更多 →
Hermes Agent 入门到深入:会学习的开源 AI Agent 是怎么工作的

Hermes Agent 入门到深入:会学习的开源 AI Agent 是怎么工作的

这两天检索 “hermes-agent” 会发现一个很有意思的现象&#xff1a;它已经不只是 Nous Research 的一个 agent 项目&#xff0c;而是开始出现在一批周边工具、桌面壳、记忆系统、代码知识图谱和自托管平台的兼容列表里。 截至 2026-07-28 15:22&#xff08;Asia/Shanghai&…

2026/7/28 16:45:52阅读更多 →
Human Resource Machine 全成就通关 第38关

Human Resource Machine 全成就通关 第38关

效率 -- HUMAN RESOURCE MACHINE PROGRAM -- COPYFROM 11 ADD 11 ADD 11 COPYTO 8 COPYFROM 10 ADD 10 ADD 10 COPYTO 7 COPYFROM 9 COPYTO 3 BUMPUP 3 BUMPUP 3 BUMPUP 3 ADD 3 …

2026/7/28 18:02:03阅读更多 →
instanceof, isinstance,isAssignableFrom的区别

instanceof, isinstance,isAssignableFrom的区别

总体来说isInstance和instanceOf都是用于判断一个对象是否是一个类或者接口的实现对象&#xff0c;但isInstance 因为.class对象可以动态获取因此泛用性更强&#xff0c;而isAssignableFrom则是用于两个类或者接口之间的比较instanceOfinstanceof运算符 只被用于对象引用变量&a…

2026/7/28 18:02:03阅读更多 →
SpringBoot面试题

SpringBoot面试题

目录1.为什么使用SpringBoot2.SpringBootApplication注解的作用1.为什么使用SpringBoot 可以基于starter构建配置没有繁琐的xml配置嵌入式服务器自动装配技术 2.SpringBootApplication注解的作用 被这个注解标注的类会成为启动类&#xff0c;该类所在的位置

2026/7/28 18:02:03阅读更多 →
【论文阅读+代码复现】GSPN:Generative Shape Proposal Network for 3D Instance Segmentation in Point Cloud

【论文阅读+代码复现】GSPN:Generative Shape Proposal Network for 3D Instance Segmentation in Point Cloud

Brief 这是一篇CVPR18上的文章&#xff0c;虽然表示是说的实例分割&#xff1b;但是听同组的同学的推荐&#xff0c;也可以做定位方面的事情&#xff0c;因此加入到了paperlist。 Abstruct Instead of treating object proposal as a direct bounding box regression problem…

2026/7/28 18:02:03阅读更多 →
Python的标准库,random()

Python的标准库,random()

random()函数产生伪随机数&#xff0c;伪随机数是采用梅森旋转算法生成的&#xff08;伪&#xff09;随机序列中的元素&#xff0c;称为随机数基本随机函数&#xff1a;seed()、random()扩展随机函数&#xff1a;ranint()、getrandbits()、uniform()、randrange()、choice()、s…

2026/7/28 18:02:03阅读更多 →
如何用Webcamoid在10分钟内将普通摄像头变成创意工作室?终极指南

如何用Webcamoid在10分钟内将普通摄像头变成创意工作室?终极指南

如何用Webcamoid在10分钟内将普通摄像头变成创意工作室&#xff1f;终极指南 【免费下载链接】webcamoid Webcamoid is a full featured and multiplatform camera suite. 项目地址: https://gitcode.com/gh_mirrors/we/webcamoid 你是否厌倦了单调的视频会议画面&#…

2026/7/28 18:00:03阅读更多 →
覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

&#x1f539; 工具基础介绍 OpenClaw 是开源生态中一款实用性较强的本地智能工具&#xff0c;凭借本地离线运行、可视化图形操作和任务自动化三大核心特性&#xff0c;赢得了众多用户的青睐。与普通在线对话AI工具不同&#xff0c;它属于能够直接操控本机软硬件的智能数字员工…

2026/7/28 4:06:39阅读更多 →
伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

所谓液压伺服阀体的精密激光焊接&#xff0c;是用激光束对阀座壳体&#xff08;通常为不锈钢或铝合金&#xff09;进行密封焊接&#xff0c;使阀体在21-35MPa的高压液压油或压缩气体中长期运行而不发生介质泄漏。液压伺服阀是高端液压系统的"大脑"。从航空航天飞行控…

2026/7/28 2:08:06阅读更多 →
D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX&#xff1a;三步实现《暗黑破坏神2》高清宽屏体验的终极指南 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 你是否还在…

2026/7/28 1:38:28阅读更多 →
告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿&#xff01;3步让你的暗影精灵笔记本重获新生 【免费下载链接】OmenSuperHub Control Omen laptop performance, fan speeds, and keyboard lighting, and unlock power limits. 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub 你是否也曾为官方Om…

2026/7/28 0:00:29阅读更多 →
RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

做 RAG 的人应该都踩过这个致命的坑&#xff1a;把几百页的财报、法规、技术手册扔给向量库&#xff0c;问一个具体问题&#xff0c;搜出来的全是沾边但没用的内容 —— 关键信息要么被硬切块拆碎了&#xff0c;要么藏在几十条结果的最下面。语义相似≠真正相关&#xff0c;这个…

2026/7/28 0:00:29阅读更多 →
抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

2026年做短视频运营&#xff0c;从抖音上扒文案早就不是偷偷抄笔记的事了。我刚开始做内容的时候&#xff0c;每天刷半小时抖音&#xff0c;手动把爆款视频的口播敲进备忘录&#xff0c;一条2分钟的视频得花十来分钟&#xff0c;碰到语速快的还要反复回听。后来试了一圈工具&am…

2026/7/28 0:00:29阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时&#xff0c;发现推理速度只有可怜的 1-2 FPS&#xff0c;而别人的演示视频却能跑到 30 FPS 以上&#xff0c;那么问题很可能不在模型本身&#xff0c;而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后&#xff0c;会直接使用官方示例…

2026/7/27 16:57:54阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一&#xff1a;为什么你需要了解 Coze 和 Dify&#xff1f;如果你对 AI 应用开发感兴趣&#xff0c;但一看到“大模型”、“智能体”、“工作流”这些词就头疼&#xff0c;觉得门槛太高&#xff0c;那这篇文章就是为你准备的。很多开发者&#xff0c;包括我自己&#…

2026/7/28 3:17:03阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会&#xff1a;配图一直是个让人头疼的问题。2026年&#xff0c;AI生图工具已经非常成熟了&#xff0c;但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1&#xff1a;速度之王2026年6月11日&#xff0c…

2026/7/28 2:35:58阅读更多 →