getInputStream与getReader方法

本文介绍了Servlet中的getInputStream与getReader方法的功能及使用场景,详细解析了如何通过这些方法读取和处理HTTP请求中的数据,包括解决中文参数的问题,并探讨了请求域属性的应用。
部署运行你感兴趣的模型镜像

getInputStream与getReader方法

getInputStream 方法用于返回的一个代表实体内容的输入流对象,其类型为javax.servlet.ServletInputStream。

getReader方法用于返回的一个代表实体内容的BufferedReader对象,返回的BufferedReader对象将实体内容中的字节数据按照请求消息中指定的字符集编码转换成文本字符串。

在调用getReader方法之前,可以调用ServletRequest的setCharacterEncoding方法指定其返回的BufferedReader对象所使用的字符集编码。

使用 ServletInputStream对象读取文本格式的实体内容

分析文件上传的请求消息结构

ServletInputStream sis = request.getInputStream();

String filePath = getServletContext().getRealPath("/body.out");

FileOutputStream fos = new FileOutputStream(filePath);

byte[] buf = new byte[1024];

int len = sis.read(buf,0,1024);

while(len != -1)

{

fos.write(buf,0,len);

len = sis.read(buf,0,1024);

}

fos.close();

sis.close();

存储在ServletRequest对象中的对象称之为请求域属性,属于同一个请求的多个处理模块之间可以通过请求域属性来传递对象数据。

与请求域属性相关的方法:

setAttribute方法

getAttribute方法

removeAttribute方法

getAttributeNames方法

请求域属性的典型应用

MVC设计模式将一次请求的响应过程分成三个功能模块(一般称之为层)来协同完成,这三个模块分别是Model(模型层)、View(视图层)、Controller(控制层)。

Model是可作为JavaBean使用的业务对象;View是负责创建显示界面的JSP页面;Controller通常是一个接收用户请求的Servlet程序,它根据请求创建相应的model对象和调用model对象的业务方法,最后再选择一个View去创建网页文档内容并回送给客户端。

Controller调用RequestDispatcher.forward方法将请求转发给作为View的JSP页面,同时将Model对象作为请求域属性传递过去,作为View的JSP页面再从请求域中检索出Model对象。

getParameter方法的中文问题

getParameter等方法在读取的参数信息时,需要进行URL解码。

对于HTTP请求消息的请求行中的URL地址后的参数,getParameter等方法进行URL解码时所采用的字符集编码在Servlet规范中没有明确规定Tomcat中的ServletRequest对象的getParameter等方法默认采用ISO8859-1字符集编码进行URL解码,因此无法返回正确的中文参数信息 。

对于POST方式下的“application/x-www-form-urlencoded”编码格式的实体内容,getParameter等方法以ServletRequest对象的getCharacterEncoding()方法返回的字符集编码对其进行URL解码。

getCharacterEncoding()方法的返回值通常为null,对于这种情况,ServletRequest对象的getParameter等方法将使用默认的ISO8859-1字符集编码对实体内容中的参数进行URL解码,因此也将无法返回正确的中文参数信息。

ServletRequest接口中定义了一个setCharacterEncoding方法来设置请求消息中的实体内容的字符集编码名称,getParameter方法将以该方法设置的字符集编码对实体内容进行URL解码。

setCharacterEncoding方法设置的是请求消息中的实体内容的字符集编码名称,它只影响getParameter方法对POST方式下的“application/x-www-form-urlencoded”编码格式的实体内容进行URL解码的结果,而不能影响getParameter方法对HTTP请求消息的请求行中的URL地址后的参数进行URL解码的结果。

一些参考经验

如果提交FORM表单的页面与处理表单请求的Servlet程序都是由同一个人或同一个项目组开发的,那么只要在处理表单提交的Servlet程序中将传递给setCharacterEncoding方法的字符集编码设置为该表单所在页面的字符集编码即可。

如果Servlet程序可以接收来自多个其他站点的FORM表单提交的数据,而每个其他站点的页面所采用的字符集编码可能各不一样,要想让Servlet程序知道FORM表单内容的字符集编码,可以在FORM表单中增加一个隐藏字段来传递当前FORM内容的字符集编码名称。

只要超链接、FORM表单的action属性设置、请求转发和重定向的URL等任何一种请求路径中要包含参数,就必须对参数部分进行URL编码。对参数进行URL编码时所选择的字符集编码应尽量与当前页面的字符集编码保持一致,也可以用一个参数来指定URL编码内容的字符集编码名称。

所有标准的浏览器和客户机终端都支持UTF-8编码,如果WEB服务器要能兼容处理各个国家和地区版本的浏览器所传递的FORM表单信息,网页文档应当使用UTF-8编码格式。

在编写应用程序时应该注意一些隐性的字符编码错误。有些程序在输出时有编码转换错误,在读取输入时返回的字符串也有转换错误,当该程序输出它所读取到的有问题的字符串时,显示的结果可能是正常的中文字符。

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

<think>好的,我现在需要回答用户关于前端开发中getReader方法的使用说明和示例的问题。首先,我得回忆一下getReader的相关知识。用户提到的getReader方法通常出现在StreamsAPI的上下文中,特别是处理可读流的数据。我记得在Fetch API的Response对象中,body属性是一个可读流,可以通过调用getReader()方法来获取读取器,这样就可以逐步读取响应的数据块。这可能用于处理大文件下载或实时数据流,比如服务器推送的消息。 接下来,我需要确认正确的使用步骤。首先,调用response.body.getReader()会返回一个ReadableStreamDefaultReader对象。然后,使用reader.read()方法返回一个Promise,该Promise解析为一个包含value和done属性的对象。当done为true时,表示流已经读取完毕;否则,value是当前的数据块,通常是Uint8Array类型,需要解码成字符串或其他格式。用户可能需要示例代码,所以我应该提供一个基本的例子,展示如何用getReader读取数据流。比如,在fetch请求后处理响应体,使用getReader逐块读取数据,并在控制台输出。同时,要提到如何处理二进制数据,比如使用TextDecoder转换成字符串。另外,用户可能关心应用场景,比如大文件下载的进度监控,或者实时处理服务器推送的数据流。结合引用中的信息,引用[3]提到用Content-Length和getReader来实现进度监控,这可以作为示例的一部分。需要说明如何计算已下载的百分比,并更新进度条。 还要注意错误处理,比如在流读取过程中发生错误时,应该捕获并处理。同时,记得在读取完毕后释放读取器,即调用reader.releaseLock(),以便其他代码可以使用该流。可能还需要提到其他方法的对比,比如直接使用response.json()或response.text(),这些方法会自动处理整个流,而getReader则允许更细粒度的控制,适用于需要逐块处理数据的场景。最后,确保代码示例符合JavaScript语法,正确使用async/await或Promise链,并注释关键步骤,方便用户理解。同时,指出相关引用来源,如引用[2]和引用[3]中的例子,以增强可信度。</think>### 前端 `getReader` 方法使用说明 `getReader` 是 Streams API 中的方法,用于**逐块读取流数据**(如网络请求的响应体),常用于处理大文件下载、实时数据流或需要分片处理内容的场景[^3]。以下是具体使用说明和示例: --- #### 核心用途 1. **流式数据读取**:直接操作二进制数据流,避免一次性加载全部内容。 2. **进度监控**:结合 `Content-Length` 实现下载进度计算[^3]。 3. **实时处理**:逐块处理服务器推送的数据(如 SSE 或自定义长连接)。 --- #### 基础使用步骤 1. **获取读取器**:通过 `response.body.getReader()` 创建 `ReadableStreamDefaultReader`。 2. **循环读取数据块**:递归调用 `reader.read()` 逐块读取数据。 3. **处理二进制数据**:使用 `TextDecoder` 解码 `Uint8Array` 类型的数据块。 4. **释放资源**:读取完成后调用 `reader.releaseLock()`。 --- #### 示例代码 ```javascript // 示例:读取流数据并拼接结果 async function fetchAndReadStream(url) { const response = await fetch(url); const reader = response.body.getReader(); // 创建读取器[^3] let result = ''; const decoder = new TextDecoder(); while (true) { const { done, value } = await reader.read(); if (done) break; result += decoder.decode(value); // 解码二进制数据块 } console.log('完整内容:', result); reader.releaseLock(); // 释放读取器 } ``` --- #### 进度监控实现 ```javascript // 示例:结合 Content-Length 显示下载进度 async function downloadWithProgress(url) { const response = await fetch(url); const totalSize = +response.headers.get('Content-Length'); // 总字节数[^3] const reader = response.body.getReader(); let receivedSize = 0; const chunks = []; while (true) { const { done, value } = await reader.read(); if (done) break; chunks.push(value); receivedSize += value.length; const progress = (receivedSize / totalSize * 100).toFixed(2); console.log(`下载进度: ${progress}%`); } const blob = new Blob(chunks); // 创建下载链接或进一步处理... } ``` --- #### 注意事项 1. **数据分片特性**:每次读取的数据块大小由浏览器控制,可能不固定。 2. **流锁定机制**:一个流同一时间只能被一个读取器占用,需释放锁后才能再次读取。 3. **错误处理**:需用 `try/catch` 包裹读取过程: ```javascript try { const { done, value } = await reader.read(); } catch (error) { console.error('流读取失败:', error); } ``` --- #### 典型应用场景 1. **大文件分片下载**:避免内存溢出,支持暂停/恢复。 2. **实时日志显示**:逐块渲染服务器推送的日志流。 3. **音视频流处理**:配合 MediaSource API 实现流媒体播放。 [^1]: 前端文件下载场景中,`getReader` 可用于分片处理下载内容。 [^3]: 进度监控的实现依赖于 `Content-Length` 和分片累计计算。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值