Servlet Request的 getInputStream() getReader() getParameter()
如果你知道了这三者的区别,请忽略
最近碰到了servlet对入参获取方式的处理问题,因为二方库处理不当,导致了获取不到入参的情况,之前也知道这三个方法不兼容,现简单介绍下
1、这三个获取入参的方法,是互斥的,也就是使用了其中一个,再使用另外的两,是获取不到数据的
(Content-Type为 multipart/form-data除外,此时getParameter只能获取在url串当中的入参,但getInputStream与getReader还可以有其中一个获取请求的流数据)
2、getInputStream() getReader()只能使用一次,getParameter单线程上可重复使用
为什么要这么设计呢?
And for good reason. It would require the servlet infrastructure to keep a copy of the input in case the servlet decided to replay reopen. That would be an unwarranted overhead.
减少不必要的资源浪费呗。
因此tomcat servlet的输入流父类ServletInputStream以及其实现类CoyoteInputStream等,继承了InputStream,但没重写reset markSupported mark这三方法,因此数据的解析是一次性的,
同样,CoyoteReader,也没有重写父类Reader的这三方法,因此也是一次性读取的,两者最终读取的都是InputBuffer里面封装的字节数据
而其他的输入流,比如ByteArrayInputStream,三方法重写了,组合使用后数据是可重复读取的,里面可以设置mark标签,前面读取过,后面可以继续读取数据,具体可以写代码测试
对于getParameter,也只是其帮我们处理好了数据而已,底层是getInputStream读取了数据,然后解析出来而已,可查看org.apache.catalina.connector.Request org.apache.tomcat.util.http.Parameters的实现,tomcat7.0.47采用了LinkedHashMap存储了解析出来后的入参(老版本基于hashtable),当第一次getParameter时,会解析所有的入参放如这个map(processParameters方法),后面的get直接从map里面获取,他里面只有用parametersParsed didQueryParameters这两标记判断是否已经解析过,所以如果要多线程getParameter,结果你懂得,但同一个线程上N次getParameter肯定没问题,因为后面都只是map的get操作,至于getParameterNames,getParameterValues,getParameterMap这些方法,只是从map里面捞数据而已
如果要避免冲突,有两个方案
1、坚决只使用其中一种办法去获取入参,就如坚决维护一党专政一样
2、重写request里面的这三个方法,把数据保持住,后面可以随便使,要修改兼容的方法很多,风险比较大,当然这也违背了最初的设计初衷
Servlet Request的 getInputStream() getReader() getParameter()的更多相关文章
- org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request; nested exception is java.io.IOException: The temporary upload location [/tmp/tomcat.1428942566812653608
一.异常信息 org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet reque ...
- SpringBoot 上传文件突然报错 Failed to parse multipart servlet request; nested exception is java.io.IOException: The temporary upload location [/tmp/tomcat.1428942566812653608
异常信息 org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request ...
- Could not parse multipart servlet request; nested exception is org.apache.commons.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed.
org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nes ...
- Could not parse multipart servlet request; nested exception is java.io.IOException: The temporary upload location
spring-boot项目,生产环境运行一段时间后,上传图片报错,如下: threw exception [Request processing failed; nested exception is ...
- jsp当做第二个servlet request的生命周期 请求 响应 不管中间经历多少个servlet 只要最后一个serlvt执行后 则生命周期结束 request的域消失
jsp当做第二个servlet request的生命周期 请求 响应 不管中间经历多少个servlet 只要最后一个serlvt执行后 则生命周期结束 request的域消失
- Springboot 上传报错: Failed to parse multipart servlet request; nested exception is java.lang.IllegalStateException: The multi-part request contained parameter data (excluding uploaded files) that exceede
Failed to parse multipart servlet request; nested exception is java.lang.IllegalStateException: The ...
- JSP内置对象--request对象 (setCharacterEncoding("GBK"),getParameter(),getParameterValues(),getParameterNames(),getServletPath(),getContextPath()
使用最多,主要用来接收客户端发送而来的请求信息,他是javax.servlet.http.HttpServletRequest接口的实例化对象. public interface HttpServle ...
- servlet request
request.getRequestURI(); request.getRequestURL(); getQueryString();//返回查询信息 getRemoteAddr();//得到来访者地 ...
- Servlet中使用getInputStream进行文件上传
据说古老了点,所以代码比较繁琐,主要用于处理文件的地方太多. 下节用SERVLET3.0的Part进行操作一下. form.html: <!DOCTYPE html> <html&g ...
随机推荐
- mysql安装方法
Window版本 1.下载 MySQL Community Server 5.7.16 http://dev.mysql.com/downloads/mysql/ 2.解压 如果想要让MySQL安装在 ...
- Day Six(Beta)
站立式会议 站立式会议内容总结 331 今天:完成闹钟功能,远程数据库采用bmob的解决方案,应用初始化bmob 遇到问题:闹钟没有取消提醒 以及多次设置提醒的问题 明天:修改闹钟问题,完成文件下载( ...
- canvas边界与摩擦力
处理物体超出画布时的三种基本状态,复位,移除,反弹 (1)检测是否越界的核心算法 if( object.x - object.width / 2 > right || object.x + ob ...
- HTML5基础知识(2)--标题标签的使用
1.HTML文档中包含各种级别的标题,各种级别的标题由<h1>到<h6>元素来定义,<h1>至<h6>标题标记中的字母h是英文headline的简称.其 ...
- ubuntu下启动、关闭tomcat,查看tomcat运行日志
启动:一般是执行sh tomcat/bin/startup.sh 停止:一般是执行sh tomcat/bin/shutdown.sh查看:执行ps -ef |grep tomcat 输出如下 *** ...
- 【BZOJ 2190】【SDOI 2008】仪仗队 欧拉筛
欧拉筛模板题 #include<cstdio> using namespace std; const int N=40003; int num=0,prime[N],phi[N]; boo ...
- swift中的结构体和枚举
Swift 里的结构体非常特殊. 类是面向对象编程语言中传统的结构单元.和结构体相比,Swift 的类支持实现继承,(受限的)反射,析构函数和多所有者. 既然类比结构体强大这么多,为什么还要使用结构体 ...
- AndroidPn
客户端的主要包说明 org.androidpn.client包下的文件 public class Constants { //包含静态数据 public class InvalidFormatExc ...
- eclipse运行一个类却运行的是另外一个类,报无法加载的类
今天是用eclipse想运行一个a.java但是却加载是b.java文件,而且还报错:无法加载的主类 查了半天才发现a.java文件中:public static void main(){}这里的ma ...
- 算法与数据结构之顺序查找(C语言)
#include<stdio.h> #include<stdlib.h> //顺序查找基本思想:从线性表的一端开始,逐个检查关键字是否满足给定的条件 int Sequentia ...