在用reset接口的时候,常常会使用request.getInputStream()方法,但是流只能读取一次,一旦想要加上一个过滤器用来检测用户请求的数据时就会出现异常。

 
在过滤器中通过流读取出用户post提交过来的数据,这是流已经读取了一次,那么该流就已经作废了,所以在contorller再次读取用户请求的数据时就会抛出异常。
解决方法
 
方法一:
 
参见:http://www.cnblogs.com/jiangxinnju/p/5709378.html
简单说一下原理,其实就是通过自定义的HttpServletRequestWrapper 备份一下流的数据,自定义HttpServletRequestWrapper 调用父类request.getInputStream()读取全部数据出来保存在一个byte数组内,当再次获取流数据的时候,自定义的HttpServletRequestWrapper 就会用byte数组重新生成一个新的流。备份的流数据仍然保留在byte数组中。
 
 
方法二:
 
request.getInputStream()方法只能使用一次,流就会作废了,其实我们还可以通过另一种方式获取用户传输的数据,那就是通过request.getReader()来获取到一个BufferedReader。这里要说一下BufferedReader是缓存流,并且BufferedReader的markSupported方法是返回true,说明BufferedReader是可以标记和回退的流。
 
BufferedReader中有defaultCharBufferSize属性
 
static { BufferedReader.defaultCharBufferSize = 8192; BufferedReader.defaultExpectedLineLength = 80; }
 
 
这里可以看出缓存大小为8192,也就是8KB大小的缓存,所以我们可以用BufferedReader的标记和重置方法来进行重复读取流。
 
 
 
结语:
 
方法二的性能会比方法一的性能较快,因为BufferedReader只存在一个实例,而不是每次调用都生成。要注意的是通过BufferedReader的标记和重置方法只能读取8KB以内的内容。超过8KB进行重复读取时,将会清空8KB前的缓存,导致标记失效,缓存内容将会丢失。比如:读取了9KB的内容,那么其中前面的1KB的内容将会在缓存中被清除掉,而只缓存了后面的8KB内容,前面的1KB内容被永久清除了,但后面的8KB内容还是能通过标记重置来进行重复读取。 (8KB内容相当于4000字)
 
方法一也是可以做成缓存流的形式,代替每次生成一个新的实例,这里就不一一介绍。
 
方法一也是有缺点的,就是遇到文件上传时内存消耗会增加,因为上传的文件也是在request流中的,一旦上传较大的文件,服务器将会内存不足导致宕机。
 
建议最好使用原生自带的缓存BufferedReader,会更加方便。

java HttpServletRequest 重复流读取的更多相关文章

  1. java HttpServletRequest 重复流读取

    在用reset接口的时候,常常会使用request.getInputStream()方法,但是流只能读取一次,一旦想要加上一个过滤器用来检测用户请求的数据时就会出现异常.   在过滤器中通过流读取出用 ...

  2. java 文件及流读取

    在Java语言的IO编程中,读取文件是分两个步骤:1.将文件中的数据转换为流,2.读取流内部的数据.其中第一个步骤由系统完成,只需要创建对应的流对象即可,对象创建完成以后步骤1就完成了,第二个步骤使用 ...

  3. Java基础---Java---IO流-----读取键盘录入、InputStreamReader、转换流、OutputStreamWriter、InputStreamReader

    字符流: FileReader FileWriter BufferedReader BufferedWriter 字节流: FileInputStream FileOutputStream Buffe ...

  4. java使用io流读取windows文件乱码问题

    出现原因: 在IDEA中,使用 FileReader 读取项目中的文本文件.由于IDEA的设置,都是默认的 UTF-8 编码,所以没有任何 问题. 但是,当读取Windows系统中创建的文本文件时,由 ...

  5. Java程序设计---io流读取文件内容并将其逆值输出到控制台

    import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.File;import java.io.FileR ...

  6. Java使用IO流读取TXT文件

    通过BufferedReader读取TXT文件window系统默认的编码是GBK,而IDE的编码多数为UTF-8,如果没有规定new InputStreamReader(new FileInputSt ...

  7. java IO流读取图片供前台显示

    最近项目中需要用到IO流来读取图片以提供前台页面展示,由于以前一直是用url路径的方式进行图片展示,一听说要项目要用IO流读取图片感觉好复杂一样,但任务下达下来了,做为程序员只有选择去执行喽,于是找了 ...

  8. Java基础IO流 ,文件读取,由易至难

    最基础的读取文件 import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;imp ...

  9. Java解决大文件读取的内存问题以及文件流的比较

    Java解决大文件读取的内存问题以及文件流的比较 传统方式 读取文件的方式一般是是从内存中读取,官方提供了几种方式,如BufferedReader, 以及InputStream 系列的,也有封装好的如 ...

随机推荐

  1. Ajax登陆,使用Spring Security缓存跳转到登陆前的链接

    Spring Security缓存的应用之登陆后跳转到登录前源地址 什么意思? 用户访问网站,打开了一个链接:(origin url)起源链接 请求发送给服务器,服务器判断用户请求了受保护的资源. 由 ...

  2. Java 工程师面试题和笔试题整理(一)

    根据自己之前收集的还有一部分自己面试的整理出来,希望能帮到面试的兄弟(2017). 海科融通 笔试题 1.有一个字符串,如果要在其中查找一个子串,都有哪些方式,写出你认为最好的一个. 2.写出线程都有 ...

  3. 彻底剖析RMI底层源码 、手写轻量级RMI框架

    https://blog.csdn.net/Z0157/article/details/82049975 User public class User { private int age; publi ...

  4. JAVA 操作远程mysql数据库实现单表增删改查操作

    package MysqlTest; import java.sql.DriverManager; import java.sql.ResultSet; import com.mysql.jdbc.C ...

  5. 如何使用LESS 深度定制Bootstrap

    一.LESS是什么? Less 是一门 CSS 预处理语言,它扩展了 CSS 语言,增加了变量.Mixin.函数等特性,使 CSS 更易维护和扩展. 中文介绍:http://lesscss.cn/ 有 ...

  6. 牛客寒假6-E.海啸

    链接:https://ac.nowcoder.com/acm/contest/332/E 题意: 有一个沿海地区,可以看作有n行m列的城市,第i行第j列的城市海拔为h[i][j]. 由于沿海,所以这个 ...

  7. GYM 101889F(树状数组)

    bit扫描坐标套路题,注意有重复的点,莽WA了. const int maxn = 1e5 + 5; struct node { ll B, F, D; bool operator < (con ...

  8. mybatis实现简单的增删查改

    接触一个新技术,首先去了解它的一些基本概念,这项技术用在什么方面的.这样学习起来,方向性也会更强一些.我对于mybatis的理解是,它是一个封装了JDBC的java框架.所能实现的功能是对数据库进行增 ...

  9. 发布好的SDE 如何注册,让数据库更新 实现arcgis 服务更新

    1, 打开 MXD 文件,前期已经发布的文件 右键  service peopertisers 右键  Service  Property 出现如下界面: “+”号 需要需要选择SDE库 不需要 选择 ...

  10. Idea安装以及破解

    软件安装包和破解工具安装包 链接 链接:https://pan.baidu.com/s/1TpCiaSsAz_I9gXyOnwKK9g 密码:qc49 1.下载完Idea工具后,点击.exe文件,进行 ...