Advertisement

关于request.getinputstream只能读取一次的探讨

  •  5星
  •     浏览量: 0
  •     大小:None
  •      文件类型:PDF


简介:
本文探讨了Java中HttpURLConnection的GET请求时,使用getInputStream方法只能一次性读取数据的问题,并提供了可能的解决方案。 在Java Web开发过程中,`HttpServletRequest`接口提供了一个方法叫作 `getInputStream()` ,用于获取客户端发送请求时附带的数据,这些数据通常以二进制形式存在,比如上传文件或者POST请求中的非表单数据等。 然而,一个重要的概念是:通过调用`getInputStream()`获得的`ServletInputStream`只能被读取一次。这是因为它的内部实现机制决定了它不支持多次读取同一个输入流的内容。具体来说,在Java中所有的字节输入流都继承自`InputStream`类,并且定义了一些基本操作,如使用 `read()` 方法从输入流中逐个字节地读取数据。 为了能够重新定位到先前的位置以便重复读取内容,可以利用`mark(int readlimit)`和`reset()`方法。但是这些功能是否可用取决于具体的子类实现情况以及调用该对象的`markSupported()`方法后返回的结果值——如果返回为false,则表示不支持此操作。 而当涉及到 `HttpServletRequest` 的 `getInputStream()` 方法时,它所返回的对象类型是专门用于处理HTTP请求数据的`ServletInputStream`。尽管它是从基础类派生出来的,并且理论上可以使用上述提到的方法来标记和重置读取位置,但实际上由于该对象并未实现这些功能(即其内部未提供对 `markSupported()` 的支持),因此一旦调用了任何一次读取操作后,原始的输入流就无法再被重新定位并再次读取。 这是因为HTTP协议本身的一个特性:请求数据在服务器端处理时是按需消费的。也就是说,在完成一次性读取之后,这些原始的数据将不再可用。这种设计确保了线程安全性和效率,并防止由于重复访问相同位置而导致的问题或混乱情况发生。 为了解决这个问题并能够多次使用同样的输入流内容进行操作,一种常见的做法是在首次调用`getInputStream()`时将其数据复制到一个可反复读取的结构中(如 `ByteArrayOutputStream` 或者 `StringBuilder`)。这样就可以随时通过访问这个副本而不会影响原始的数据源。 另外,在处理表单提交方式发送请求参数的情况下,可以通过使用 `HttpServletRequest.getParameter()` 和 `getParts()` 方法来获取请求中的数据,从而避免直接操作输入流带来的不便或复杂性。这不仅简化了代码逻辑也提高了效率和安全性。 综上所述,“`ServletInputStream`只能被读取一次”这一特性是由其设计特点以及HTTP协议的性质决定的。理解这一点对于处理上传文件、大块二进制数据传输或者自定义请求格式等场合至关重要,开发者需要确保在首次完成所有必要的读取操作之后能够妥善地保存或复制这些信息以备后续使用。同时掌握Java IO流的基本原理和方法(如 `read()` 、`mark()` 和 `reset()`)对于优化Web应用的输入处理部分有着重要的意义。

全部评论 (0)

还没有任何评论哟~
客服
客服
  • request.getinputstream
    优质
    本文探讨了Java中HttpURLConnection的GET请求时,使用getInputStream方法只能一次性读取数据的问题,并提供了可能的解决方案。 在Java Web开发过程中,`HttpServletRequest`接口提供了一个方法叫作 `getInputStream()` ,用于获取客户端发送请求时附带的数据,这些数据通常以二进制形式存在,比如上传文件或者POST请求中的非表单数据等。 然而,一个重要的概念是:通过调用`getInputStream()`获得的`ServletInputStream`只能被读取一次。这是因为它的内部实现机制决定了它不支持多次读取同一个输入流的内容。具体来说,在Java中所有的字节输入流都继承自`InputStream`类,并且定义了一些基本操作,如使用 `read()` 方法从输入流中逐个字节地读取数据。 为了能够重新定位到先前的位置以便重复读取内容,可以利用`mark(int readlimit)`和`reset()`方法。但是这些功能是否可用取决于具体的子类实现情况以及调用该对象的`markSupported()`方法后返回的结果值——如果返回为false,则表示不支持此操作。 而当涉及到 `HttpServletRequest` 的 `getInputStream()` 方法时,它所返回的对象类型是专门用于处理HTTP请求数据的`ServletInputStream`。尽管它是从基础类派生出来的,并且理论上可以使用上述提到的方法来标记和重置读取位置,但实际上由于该对象并未实现这些功能(即其内部未提供对 `markSupported()` 的支持),因此一旦调用了任何一次读取操作后,原始的输入流就无法再被重新定位并再次读取。 这是因为HTTP协议本身的一个特性:请求数据在服务器端处理时是按需消费的。也就是说,在完成一次性读取之后,这些原始的数据将不再可用。这种设计确保了线程安全性和效率,并防止由于重复访问相同位置而导致的问题或混乱情况发生。 为了解决这个问题并能够多次使用同样的输入流内容进行操作,一种常见的做法是在首次调用`getInputStream()`时将其数据复制到一个可反复读取的结构中(如 `ByteArrayOutputStream` 或者 `StringBuilder`)。这样就可以随时通过访问这个副本而不会影响原始的数据源。 另外,在处理表单提交方式发送请求参数的情况下,可以通过使用 `HttpServletRequest.getParameter()` 和 `getParts()` 方法来获取请求中的数据,从而避免直接操作输入流带来的不便或复杂性。这不仅简化了代码逻辑也提高了效率和安全性。 综上所述,“`ServletInputStream`只能被读取一次”这一特性是由其设计特点以及HTTP协议的性质决定的。理解这一点对于处理上传文件、大块二进制数据传输或者自定义请求格式等场合至关重要,开发者需要确保在首次完成所有必要的读取操作之后能够妥善地保存或复制这些信息以备后续使用。同时掌握Java IO流的基本原理和方法(如 `read()` 、`mark()` 和 `reset()`)对于优化Web应用的输入处理部分有着重要的意义。
  • 调频与二调频误区及AGC.docx
    优质
    本文深入分析了电力系统中一次调频和二次调频常见的误解,并对自动发电控制(AGC)进行了详细讨论。 对一次调频和二次调频容易造成误解的是:认为一次调频对应的频率波动幅值较小,而二次调频对应较大的频率波动;进一步地,有人错误地将三次调频与最大幅度的频率变化联系在一起。
  • 方阵n幂求解方法
    优质
    本文深入探讨了求解方阵高次幂的有效方法,分析了几种常见算法的优劣,并提出了一种新的优化策略,为矩阵运算提供理论支持。 方阵n次幂的求解方法探讨:张靖芝、李薇薇 方阵高次幂在高等代数题解及矩阵稳定性讨论等方面具有广泛应用,但其求解通常较为困难。尽管它的运算遵循矩阵乘法规律,但在实际操作中却存在不少挑战。
  • Avalon-ST接口帧IP核设计与应用
    优质
    本篇文章深入探讨了基于Avalon-ST接口的帧读取IP核的设计原理及其在高速数据传输系统中的应用,旨在提高系统的兼容性和效率。 SoPC(可编程片上系统)将软核处理器Nios II、存储器及输入输出接口等IP核心集成到单个FPGA芯片上,用于嵌入式系统的研发与电子信息处理。作为一种特殊的嵌入式系统,SOPC不仅是一个在单一硅片上的片上系统(SOC),而且还是一个可编程的系统,具备灵活的设计方式:可以裁剪、扩展和升级,并且支持软硬件在系统中的重新配置功能。 SoPC结合了软件系统的灵活性与硬件性能的优势。通过使用SoPC Builder工具,可以将定制化的IP核心集成到Nios II处理器中,这样既增强了这些IP核的移植性和复用性,也提升了产品的设计效率。
  • STM32 Flash写及HardFault_Handler问题
    优质
    本文深入探讨了在使用STM32微控制器时遇到的Flash存储器读写操作以及HardFault_Handler中断处理程序的相关问题和解决方案。 今天调试程序的时候需要将掉电前的数据存储到Flash中,在下次初始化时再读取这些数据。刚开始查找STM32的Flash操作资料时发现大部分内容都是废话,真正有用的信息很少。因此我把经过调试验证过的Flash读写子函数分享给大家。
  • 种开稳压电源设计
    优质
    本文旨在探讨和设计一种高效的开关稳压电源,通过分析现有技术的优缺点,提出创新方案以提高电源效率、稳定性及可靠性。 开关稳压电源是一种高效的电力转换装置,在电子设备中广泛应用以提供稳定的直流电能。其工作原理是通过控制开关来将输入的交流或直流电压转化为所需的稳定直流输出,具备体积小、重量轻以及高效率和大功率的特点,因此在现代电子产品中有重要应用价值。 PWM(脉冲宽度调制)技术对开关稳压电源的设计至关重要,它能够调节脉冲长度以管理开关管的状态切换时间,从而保持稳定的输出电压。使用PWM可以显著提高转换效率并减少能量浪费。 KA3525是一款具备欠压锁定和软启动功能的PWM控制器,在基本性能上有所增强,并且在电路启动时缓慢增加供电量,降低电流峰值以提升稳定性。此外,它还改进了振荡器与输出级的设计,使整体性能更加优越。 IRF540N是一种具有低导通电阻及高耐压特性的N沟道场效应晶体管,在开关稳压电源中作为关键的切换元件使用。其特性有助于减少能量损失并提升整个系统的转换效率。 DC-DC变换器在开关稳压电源设计中扮演核心角色,负责进行升、降电压操作。常见的类型包括Boost(升压)、Buck(降压)和Buck-Boost等电路结构,在此方案选择的是Boost升压斩波电路,能够在输入电压较低的情况下产生较高的输出电压。 过流保护系统是保障电源安全的关键组件之一,用于监控并防止电流超出设定限值。它通常由采样电阻、AD转换器以及控制逻辑构成,并在检测到异常时立即采取措施以避免损坏。 本方案中的开关稳压电源包括隔离变压器、芯片供电部分、整流滤波电路、DC-DC变换器和过流保护系统等组件,其中整流滤波环节用来从交流电中提取稳定的直流电压供给后续的升压或降压转换;而芯片供电模块则确保各控制单元获得稳定的工作电源。 另外采用了MC34063开关稳压IC来提供±15V、5V的标准电力供应,并且为了进一步提高电路可靠性和稳定性,可以考虑采用LM2596和LM2577等现成的DC-DC可调电压模块。测试结果显示该电源设计具有优秀的输出稳定特性,在各种输入条件下均能保持一致的性能表现。 综上所述,本段落提出的设计方案运用了PWM技术,并通过精心挑选核心元件及优化电路布局实现了高效、简洁和高精度的目标,不仅满足开关稳压电源的基本需求,还展示了对系统稳定性和效率的高度把控能力。随着电子技术的进步,这种高效的电源设计方法将会有更广阔的应用前景。
  • 跨平台CString源码
    优质
    本文深入探讨了跨平台CString源码的设计与实现细节,分析其在不同操作系统间的兼容性及优化策略。 // =============================================================================// // 文件:StdString.h // // 作者:Joe OLeary (参考外部帮助在评论中标记) // 如果您发现此代码中的任何错误,请告知我: jmoleary@earthlink.net 最新版本的此代码应始终可通过以下链接获取: 这个头文件声明了CStdStr模板。该模板继承自标准C++库基本字符串(basic_string<>)模版,并添加了如下便利功能: - 完整的一套MFC CString函数,包括隐式转换 - 对COM IStream接口的写入/读取操作支持 - 用于STL算法的功能对象 从该模板中实例化两个类:CStdStringA和CStdStringW。名称CStdString是根据UNICODE宏设置定义这两个中的一个。 此头文件还声明了我们自己的版本MFC/ATL UNICODE-MBCS转换宏,我们的版本与Microsoft的完全相同以促进移植性。 注意: 如果您在使用该代码时构建的是MFC或ATL,则应首先包含afx.h或atlbase.h,视情况而定。 贡献者名单: 许多人帮助我改进和完善了这个类。这是一个很长的列表,但要为自己辩护的话,在我对此代码进行了两次重大重写之后许多改进变得必要起来。其他人则帮助提高了CString外观。 这些人包括(按时间顺序): - Pete the Plumber (???) - Julian Selman - Chris (of Melbsys) - Dave Plummer - John C Sipos - Chris Sells - Nigel Nunn ... (省略部分贡献者名单) 修订历史: 2005年1月10日:感谢Don Beusee指出将长度检查格式化函数映射到无长度检查CRT等价物的危险性,并激励我优化Replace()实现。 ... 版权: 2002 Joseph M. OLeary。此代码完全免费使用,可以在任何地方使用、重写或重构它。如果您能利用软件获利,恭喜您!我喜欢资本主义。如果以任何形式重新分发,请尽量保留本通知。 ============
  • C#实现CPU温度及自动开机功多种方法
    优质
    本篇文章详细探讨了使用C#编程语言实现读取计算机CPU温度以及基于此条件进行自动关机或开机的功能,并介绍了几种不同的实现方法。适合对系统管理与自动化脚本感兴趣的开发者阅读。 C#读取CPU温度并加入了电脑自动开关机功能,通过多种方法实现这一实用的功能。这段描述强调了利用C#编程语言来监测计算机的CPU温度,并且能够根据设定条件自动进行开机或关机操作,提供了实际应用中的灵活性和便利性。
  • Tc397Lwip RAW UPD程序移植
    优质
    本文为系列文章的第一部分,主要探讨了将LwIP RAW UDP程序移植到Tc397平台的过程和技术细节,分析了遇到的问题及解决方案。 基于Tc397的Lwip RAW UPD程序移植(一) 本段落主要介绍如何将Lwip RAW UDP程序移植到Tc397平台上。在进行移植的过程中,需要考虑平台特有的硬件特性和软件环境差异,并对原有的代码做出相应的修改和优化。 首先,在开始移植工作前,请确保已经熟悉了目标平台的开发文档和技术手册,以便更好地理解其架构特点及编程接口。接下来,根据Lwip协议栈的工作原理以及Tc397的具体需求进行适配性调整。 整个移植过程大致可以分为以下几个步骤: 1. 环境搭建与配置; 2. 代码修改和功能测试; 3. 性能优化及调试。 通过这些操作可以使基于TCP/IP的网络通信在目标平台上顺利运行。
  • tf.data.Dataset.map和tf.data.Dataset.interleave
    优质
    本文深入探讨了TensorFlow中两个重要的数据集操作函数——map和interleave的功能、应用场景及优化技巧,帮助读者更好地理解和使用它们。 使用`map()`函数可以对数据集中的每个元素应用一个转换函数(一对一映射)。该操作会将给定的`map_func`应用于此数据集的所有元素,并生成一个新的包含这些变换后结果的数据集,保持原始顺序不变。 例如: ```python a = Dataset.range(1, 6) # 数据集中有五个整数:[ 1, 2, 3, 4, 5 ] a.map(lambda x: x + 1) # 将每个元素增加一后得到新的数据集: [ 2, 3, 4, 5, 6 ] ``` `map_func`的参数类型根据输入的数据结构决定。例如,如果数据集中包含的是整数,则传递给`map()`函数的lambda表达式或其它转换函数应该能够接收一个整数作为输入,并返回一个新的值(同样可以是整数或其他类型的对象)。