拦截器如何获取HttpServletRequest里body数据
发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,这篇文章主要讲解了"拦截器如何获取HttpServletRequest里body数据",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"拦截器如何获取Htt
千家信息网最后更新 2026年11月01日拦截器如何获取HttpServletRequest里body数据
这篇文章主要讲解了"拦截器如何获取HttpServletRequest里body数据",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"拦截器如何获取HttpServletRequest里body数据"吧!
一、问题
通过在拦截器中获取request中的json数据,我们可以实现对参数进行校验和改写。问题是参数只能在拦截器里获取一次,往后在controller层就无法获取数据,提示body为空。
在网上查找资料后发现,request的输入流只能读取一次,那么这是为什么呢?
那是因为流对应的是数据,数据放在内存中,有的是部分放在内存中。read 一次标记一次当前位置(mark position),第二次read就从标记位置继续读(从内存中copy)数据。 所以这就是为什么读了一次第二次是空了。 怎么让它不为空呢?只要inputstream 中的pos 变成0就可以重写读取当前内存中的数据。javaAPI中有一个方法public void reset() 这个方法就是可以重置pos为起始位置,但是不是所有的IO读取流都可以调用该方法!ServletInputStream是不能调用reset方法,这就导致了只能调用一次getInputStream()
二、解决办法
HttpServletRequestWrapper是 httpServletRequest 的包装类
新建一个类继承HttpServletRequestWrapper实现对 httpServletRequest 的装饰,用来获取 body 数据
public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper { private final byte[] body; private String bodyStr; public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException { super(request); String bodyString = getBodyString(request); body = bodyString.getBytes(Charset.forName("UTF-8")); bodyStr=bodyString; } public String getBodyStr() { return bodyStr; } @Override public ServletInputStream getInputStream() throws IOException { final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body); return new ServletInputStream() { @Override public int read() throws IOException { return byteArrayInputStream.read(); } @Override public boolean isFinished() { return false; } @Override public boolean isReady() { return false; } @Override public void setReadListener(ReadListener readListener) { } }; } public String getBodyString(HttpServletRequest request) throws IOException { StringBuilder sb = new StringBuilder(); InputStream inputStream = null; BufferedReader reader = null; try { inputStream = request.getInputStream(); reader = new BufferedReader( new InputStreamReader(inputStream, Charset.forName("UTF-8"))); char[] bodyCharBuffer = new char[1024]; int len = 0; while ((len = reader.read(bodyCharBuffer)) != -1) { sb.append(new String(bodyCharBuffer, 0, len)); } } catch (IOException e) { e.printStackTrace(); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } return sb.toString(); }}再新建一个 filter 实现对传入的 httpServletRequest 的转换
@WebFilter(filterName = "httpServletRequestWrapperFilter", urlPatterns = {"/*"})public class HttpServletRequestWrapperFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { ServletRequest requestWrapper = null; if (request instanceof HttpServletRequest) { HttpServletRequest httpRequest = (HttpServletRequest) request; //遇到post方法才对request进行包装 String methodType = httpRequest.getMethod(); if ("POST".equals(methodType)) { requestWrapper = new BodyReaderHttpServletRequestWrapper( (HttpServletRequest) request); } } if (null == requestWrapper) { chain.doFilter(request, response); } else { chain.doFilter(requestWrapper, response); } } @Override public void destroy() { }}最后在拦截器就可以获取request中body数据
if(request instanceof BodyReaderHttpServletRequestWrapper ){ System.out.println(((BodyReaderHttpServletRequestWrapper) request).getBodyStr()); }经测试发现并不影响controller层获取body数据
为什么需要在 filter 里进行对 httpServletRequest 的包装转换,直接在拦截器里进行包装不行嘛?
过滤器(Filter)和拦截器(Interceptor)之间的最大区别就是,过滤器可以包装Request和Response,而拦截器并不能用代码描述拦截器和过滤器的流程大概就是这样的:拦截器:void run () { Request request = new Request(); preHandle(request); service(request);}preHandler(Request request) { request = new RequestWrapper(request); //在这里修改Request的引用,不会影响到service方法的request}过滤器void run () { Request request = new Request(); doFilter(request);}doFilter(Request request) { request = new RequestWrapper(request); //在这里修改Request的引用,会影响到service方法的request service(request);}感谢各位的阅读,以上就是"拦截器如何获取HttpServletRequest里body数据"的内容了,经过本文的学习后,相信大家对拦截器如何获取HttpServletRequest里body数据这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!
数据
拦截器
方法
就是
包装
内存
过滤器
位置
问题
学习
影响
内容
参数
标记
UTF-8
不行
最大
有的是
之间
代码
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
互联网科技
互联网扶贫科技
关于新基建和互联网科技
深圳科技互联网
迪茉互联网科技
互联网科技缩写
顺玮阁互联网科技
成都狮子座互联网科技
科技大学互联网专业好不好
剑昆互联网络科技有限公司临桂
辽宁互联网新科技
广州新华互联网科技学校电竞方面
美国互联网科技实力
智帮互联网科技公司最近动向
杭州披云加互联网科技有限公司
抖集互联网科技技术咨询
版纳互联网科技选哪家
陕西彩京云互联网科技有限公司
广东猫王互联网科技有限公司电话
网互联网络科技
互联网科技财经
互联网科技的
互联网科技公司发展
互联网科技公司招聘
重庆威客帮互联网科技
贵州叶脉互联网科技有限公司所属行业
搜狐科技互联网
互联网科技大赛获奖感言
广东鹅鹅鹅互联网科技有限公司
西安左小互联网科技有限公司