zoukankan      html  css  js  c++  java
  • 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里面的这三个方法,把数据保持住,后面可以随便使,要修改兼容的方法很多,风险比较大,当然这也违背了最初的设计初衷

  • 相关阅读:
    SCOI2014 方伯伯的OJ onlinejudge
    【JZOJ4854】【NOIP2016提高A组集训第6场11.3】小澳的坐标系
    【JZOJ4847】【NOIP2016提高A组集训第5场11.2】夕阳
    【JZOJ4846】【NOIP2016提高A组集训第5场11.2】行走
    【JZOJ4845】【NOIP2016提高A组集训第5场11.2】寻找
    【JZOJ4841】【NOIP2016提高A组集训第4场11.1】平衡的子集
    【JZOJ4840】【NOIP2016提高A组集训第4场11.1】小W砍大树
    【JZOJ4835】【GDOI2017模拟10.31】量化交易
    【JZOJ4831】【NOIP2016提高A组集训第3场10.31】方程式
    【JZOJ4832】【NOIP2016提高A组集训第3场10.31】高维宇宙
  • 原文地址:https://www.cnblogs.com/kabi/p/6169452.html
Copyright © 2011-2022 走看看