返回顶部
首页 > 资讯 > 精选 >怎么构建可重复读取inputStream的request
  • 640
分享到

怎么构建可重复读取inputStream的request

2023-06-29 12:06:56 640人浏览 薄情痞子
摘要

本篇内容介绍了“怎么构建可重复读取inputStream的request”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!构建可重复读取inpu

本篇内容介绍了“怎么构建可重复读取inputStream的request”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

构建可重复读取inputStream的request

我们知道,request的inputStream只能被读取一次,多次读取将报错,那么如何才能重复读取呢?答案之一是:增加缓冲,记录已读取的内容。

代码如下所示:

import lombok.extern.log4j.Log4j2;import org.springframework.mock.WEB.DelegatingServletInputStream;import javax.servlet.ServletInputStream;import javax.servlet.Http.httpservletRequest;import javax.servlet.http.HttpServletRequestWrapper;import java.io.*;@Log4j2public class RepeatedlyReadRequestWrapper extends HttpServletRequestWrapper {    private static final int BUFFER_START_POSITION = 0;    private static final int CHAR_BUFFER_LENGTH = 1024;        private final String body;        public RepeatedlyReadRequestWrapper(HttpServletRequest request) {        super(request);        StringBuilder stringBuilder = new StringBuilder();        InputStream inputStream = null;        try {            inputStream = request.getInputStream();        } catch (IOException e) {            log.error("Error reading the request body…", e);        }        if (inputStream != null) {            try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream))) {                char[] charBuffer = new char[CHAR_BUFFER_LENGTH];                int bytesRead;                while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {                    stringBuilder.append(charBuffer, BUFFER_START_POSITION, bytesRead);                }            } catch (IOException e) {                log.error("Fail to read input stream",e);            }        } else {            stringBuilder.append("");        }        body = stringBuilder.toString();    }    @Override    public ServletInputStream getInputStream() throws IOException {        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());        return new DelegatingServletInputStream(byteArrayInputStream);    }}

接下来,需要一个对应的Filter.

代码如下所示:

import javax.servlet.*;import javax.servlet.http.HttpServletRequest;import java.io.IOException;public class RepeatlyReadFilter implements Filter {    @Override    public void init(FilterConfig filterConfig) throws ServletException {        //Do nothing    }    @Override    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {        if (request instanceof HttpServletRequest) {            request = new RepeatedlyReadRequestWrapper((HttpServletRequest) request);        }        chain.doFilter(request, response);    }    @Override    public void destroy() {        //Do nothing    }}

最后,需要在web.xml中,增加该Filter的配置(略)。 

request中inputStream多次读取

在使用HTTP协议实现应用间接口通信时,服务端读取客户端请求过来的数据,会用到request.getInputStream(),第一次读取的时候可以读取到数据,但是接下来的读取操作都读取不到数据。

原因

一个InputStream对象在被读取完成后,将无法被再次读取,始终返回-1;

InputStream并没有实现reset方法(可以重置首次读取的位置),无法实现重置操作;

解决方法(缓存读取到的数据)

使用request、session等来缓存读取到的数据,这种方式很容易实现,只要setAttribute和getAttribute就行;

使用HttpServletRequestWrapper来包装HttpServletRequest,在中初始化读取request的InputStream数据,以byte[]形式缓存在其中,然后在Filter中将request转换为包装过的request;

代码

编写rHttpServletRequestWrapper子类,用来处理请求数据

import java.io.BufferedReader;import java.io.ByteArrayInputStream;import java.io.IOException;import java.io.InputStreamReader;import java.NIO.charset.Charset;import java.util.Enumeration;import javax.servlet.ReadListener;import javax.servlet.ServletInputStream;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;import lombok.extern.slf4j.Slf4j;@Slf4jpublic class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper{private final byte[] body;public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException{super(request);Enumeration<String> e = request.getHeaderNames();while (e.hasMoreElements()){String name = (String) e.nextElement();String value = request.getHeader(name);log.debug("HttpServletRequest头信息:{}-{}", name, value);}body = HttpHelper.getBodyString(request).getBytes(Charset.forName("UTF-8"));}@Overridepublic BufferedReader getReader() throws IOException{return new BufferedReader(new InputStreamReader(getInputStream()));}@Overridepublic ServletInputStream getInputStream() throws IOException{final ByteArrayInputStream bais = new ByteArrayInputStream(body);return new ServletInputStream(){@Overridepublic boolean isFinished(){return false;}@Overridepublic boolean isReady(){return false;}@Overridepublic void setReadListener(ReadListener listener){}@Overridepublic int read() throws IOException{return bais.read();}};}@Overridepublic String getHeader(String name){return super.getHeader(name);}@Overridepublic Enumeration<String> getHeaderNames(){return super.getHeaderNames();}@Overridepublic Enumeration<String> getHeaders(String name){return super.getHeaders(name);}}

调用

public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException{HttpServletRequest httpRequest = (HttpServletRequest) request;HttpServletResponse httpResponse = (HttpServletResponse) response;ServletRequest requestWrapper = null;requestWrapper = new BodyReaderHttpServletRequestWrapper(httpRequest);//数据读取处理//...//将requestWrapper专递给后面的过滤器filterChain.doFilter(requestWrapper, httpResponse);}

“怎么构建可重复读取inputStream的request”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: 怎么构建可重复读取inputStream的request

本文链接: https://lsjlt.com/news/324806.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 怎么构建可重复读取inputStream的request
    本篇内容介绍了“怎么构建可重复读取inputStream的request”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!构建可重复读取inpu...
    99+
    2023-06-29
  • 如何构建可重复读取inputStream的request
    目录构建可重复读取inputStream的requestrequest中inputStream多次读取原因解决方法(缓存读取到的数据)代码构建可重复读取inputStream的req...
    99+
    2024-04-02
  • Springboot如何设置过滤器及重复读取request里的body
    目录HttpServletRequest的输入流只能读取一次的原因重复读取body中数据的方法springboot的过滤器上面的getBody的代码需求: request的conte...
    99+
    2024-04-02
  • SpringBoot v2.2以上重复读取Request Body内容的解决方案
    目录SpringBootv2.2以上重复读取RequestBody内容一、需求二、解决方案三、遇到问题四、问题排查解决方案SpringBoot读取Request参数的坑后端拿参数相关...
    99+
    2024-04-02
  • mysql怎么实现可重复读
    要实现可重复读,可以通过以下两种方式:1. 使用事务隔离级别为"可重复读":在MySQL中,可通过设置事务隔离级别来实现不同的并发控...
    99+
    2023-09-15
    mysql
  • jmeter怎么读取json重复数据
    要在JMeter中读取重复的JSON数据,可以使用以下步骤:1. 添加一个HTTP请求,用于发送请求和接收JSON响应。2. 在HT...
    99+
    2023-08-15
    jmeter json
  • 怎么构建可重用的SQL拼接组件
    构建可重用的SQL拼接组件需要考虑以下几个方面: 参数化查询:在拼接SQL语句时,应该使用参数化查询,而不是直接拼接变量值到SQ...
    99+
    2024-04-29
    SQL
  • 不可重复读和幻读的区别是什么
    本篇文章和大家了解一下不可重复读和幻读的区别是什么。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。不可重复读和幻读区别:不可重复读的重点是修改;同样的条件,第1次和第2次读取的值不一样。幻...
    99+
    2024-04-02
  • MySQL 中怎么实现可重复读操作
    这篇文章将为大家详细讲解有关MySQL 中怎么实现可重复读操作,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。账户表(省去其他字段)结构如下:CREATE&n...
    99+
    2024-04-02
  • MySQL的不可重复读和幻读是什么意思
    这篇文章主要介绍“MySQL的不可重复读和幻读是什么意思”,在日常操作中,相信很多人在MySQL的不可重复读和幻读是什么意思问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”My...
    99+
    2024-04-02
  • 函数拼图:构建灵活、可重复使用的代码
    函数拼图的概念 函数拼图是一种软件开发技术,将复杂代码分解为较小的、可重用的函数。每个函数执行特定任务,并与其他函数相互协作以完成更大的目标。通过这种方式,您可以创建易于理解、修改和维护的代码。 函数拼图的好处 函数拼图提供了以下主要好...
    99+
    2024-03-02
    函数拼图、代码重用、模块化代码、可读性、可维护性
  • Gateway网关自定义拦截器的不可重复读取数据问题
    目录Gateway网关自定义拦截器的不可重复读取数据统一网关Gateway一、为什么需要网关二、搭建网关服务三、路由断言工厂四、路由过滤器五、跨域问题处理Gateway网关自定义拦截...
    99+
    2024-04-02
  • java怎么创建不重复的集合?
    java怎么创建不重复的集合?java中创建不重复的集合有多种方法,下面我们介绍Java中创建不重复集合的四种常用方法。方法一、需要一个存储去重后元素的数组,然后两层循环,外层遍历原数组,内容逐个判断是否和之后的元素重复,然后再提出来存入新...
    99+
    2021-04-07
    java入门 java 集合
  • Vue中怎么创建一个可重用的Transition
    这篇文章将为大家详细讲解有关Vue中怎么创建一个可重用的Transition,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。原始transition组件和CS...
    99+
    2024-04-02
  • php怎么提取数组中不重复的值
    提取步骤:1、利用array_count_values()函数统计数组中元素的出现次数,语法“array_count_values(原数组)”,会返回一个关联数组,其元素的键名是原数组的值,键值是该值在原数组中出现的次数;2、利用array...
    99+
    2022-07-13
    php php数组
  • php怎么获取2个数组中不重复的值
    本教程操作环境:windows7系统、PHP7.1版、DELL G3电脑在php中,获取2个数组不重复的值,也就是比较两个数组,找出两个数组中的不同元素,即就差集。下面我们就来看看php中怎么比较两个数组,就差集。方法1、使用array_d...
    99+
    2019-02-10
    php 数组
  • 怎么使用Docker Compose构建复杂的多容器App
    这篇文章主要介绍“怎么使用Docker Compose构建复杂的多容器App”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么使用Docker Compose构建复杂的多容器Ap...
    99+
    2023-06-30
  • WPF怎么使用Dragablz构建可拖拽分离的Tab页程序
    今天小编给大家分享一下WPF怎么使用Dragablz构建可拖拽分离的Tab页程序的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧...
    99+
    2023-07-02
  • JAVA NIO怎么构建I/O多路复用的请求模型
    这篇文章主要介绍“JAVA NIO怎么构建I/O多路复用的请求模型”,在日常操作中,相信很多人在JAVA NIO怎么构建I/O多路复用的请求模型问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”JAVA NIO怎...
    99+
    2023-06-02
  • Raid磁盘阵列重建后怎么恢复原来的数据
    这篇文章主要介绍了Raid磁盘阵列重建后怎么恢复原来的数据的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Raid磁盘阵列重建后怎么恢复原来的数据文章都会有所收获,下面我们一起来看看吧。【raid数据恢复故障描述...
    99+
    2023-06-04
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作