如果你知道了这三者的区别,请忽略

最近碰到了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()的更多相关文章

  1. 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 ...

  2. 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 ...

  3. 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 ...

  4. 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 ...

  5. jsp当做第二个servlet request的生命周期 请求 响应 不管中间经历多少个servlet 只要最后一个serlvt执行后 则生命周期结束 request的域消失

    jsp当做第二个servlet  request的生命周期   请求 响应  不管中间经历多少个servlet 只要最后一个serlvt执行后 则生命周期结束  request的域消失

  6. 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 ...

  7. JSP内置对象--request对象 (setCharacterEncoding("GBK"),getParameter(),getParameterValues(),getParameterNames(),getServletPath(),getContextPath()

    使用最多,主要用来接收客户端发送而来的请求信息,他是javax.servlet.http.HttpServletRequest接口的实例化对象. public interface HttpServle ...

  8. servlet request

    request.getRequestURI(); request.getRequestURL(); getQueryString();//返回查询信息 getRemoteAddr();//得到来访者地 ...

  9. Servlet中使用getInputStream进行文件上传

    据说古老了点,所以代码比较繁琐,主要用于处理文件的地方太多. 下节用SERVLET3.0的Part进行操作一下. form.html: <!DOCTYPE html> <html&g ...

随机推荐

  1. C# 退出应用程序办法

    Application.Exit();//好像只在主线程可以起作用,而且当有线程,或是阻塞方法的情况下,很容易失灵   this.Close();//只是关闭当前窗体.   Application.E ...

  2. word2vec 实践

    关于word2vec,这方面无论中英文的参考资料相当的多,英文方面既可以看官方推荐的论文,也可以看gensim作者Radim Řehůřek博士写得一些文章.而中文方面,推荐 @licstar的< ...

  3. JavaScript的理解记录(2)

    一.表达式与运算符: 1.对于属性访问表达式: var arr = {first:"hh","second":"gg",third:null ...

  4. 用户 'IIS APPPOOL\***' 登录失败

    用户 'IIS APPPOOL\DefaultAppPool' 登录失败. 我在windows8中安装了iis之后添加了我做的网站打开之后提示用户 'IIS APPPOOL\DefaultAppPoo ...

  5. 写启动界面Splash的正确姿势,解决启动白屏(转)

    原文链接:http://www.jianshu.com/p/cd6ef8d3d74d 从我学习写第一个android项目以来,我都是这样写着启动界面: 在里面做一些事,比如:第一次启动时拷贝数据. 然 ...

  6. 02python算法-递推

    递推 1什么是递推?:根据已有节点的值,以及规律推出之后节点的值 2为什么要用递推:简单的解决有规矩事件 3怎么用?: 我们举个经典的例子: 如果1对兔子每月能生1对小兔子,而每对小兔在它出生后的第3 ...

  7. java-汉字转换拼音-pinyin4j.jar

    使用pinyin4j将汉字转成拼音,附件为pinyin4j的jar包 import net.sourceforge.pinyin4j.PinyinHelper; import net.sourcefo ...

  8. 使用navicat连接mysql要报10038的错误

    1.mysql的设置 (1)授权mysql>grant all privileges on *.*  to  'root'@'%'  identified by 'youpassword'  w ...

  9. 新手Oracle安装及使用入门

    一.安装Oracle Step1 下载oracle压缩包并解压到同一文件夹下面 Step2 双击setup.exe进行安装 Step3:进入如下界面配置: 邮箱可不填,去掉更新 除了设置密码,其他均可 ...

  10. genymotion访问电脑的localhost

    用来进行android测试时使用genymotion,genymotion是运行在virtualbox中的,virtualbox为两者建立了连接,在linux下通过ifconfig可以看到有一个叫做v ...