HttpServletRequest 的三个方法 request.getParameter()、request.getInputStream()、request.getReader()
1.request.getParameter(String s)
1.1 返回:
Map (String,String),当参数中存在重复的key时,用这个方法只能获取到其中一个的值。
1.2 获取参数范围:
1.请求url的Query String部分
2.编码类型为application/x-www-form-urlencoded(参数被放入到Form Data)
注意:当Content-Type设置为 “application/json” ,请求参数是会被放入Reqest Payload
2.request.getParameterMap()
2.1返回:
Map(String, String[]),当参数中存在重复的key时,这个方法会把这个key的所有值,以数组的形式接收。在使用时需要注意。
2.2 获取参数范围:
同request.getParameter(String s)
3.request.getInputStream()
3.1返回:
getInputStream方法返回一个代表实体内容的输入流对象,类型为javax.servlet.ServletInputStream,可以读取HTTP请求消息中的实体内容。如果实体内容中包含二进制数据,那么就只能使用此方法返回的输入流对象来读取。
String str = ""; InputStream in = request.getInputStream(); InputStreamReader reader = new InputStreamReader(in); BufferedReader bd = new BufferedReader(reader); while ((inputLine = bd.readLine()) != null) { str += inputLine; }
4.request.getReader()
4.1返回:
getReader方法用于返回一个代表实体内容的BufferReader对象,返回的BufferReader对象将实体内容中的字节数据按照请求消息中指定的字符集编码转换成文本字符串。
总结
1. Query String的参数通过request.getParameter()获取。
2. 当content-type为application/x-www-form-urlencoded时,用request.getParameter()方法来获取请求参数值。但当请求内容不是该类型时,调用request.getInputStream()或request.getReader()方法来获取请求内容值。
其实content-type为application/x- www-form-urlencoded时也可以直接调用request.getInputStream()或request.getReader()方法获取到请求内容再解析出具体都参数,但前提是还没调用request.getParameter()方法。此时当request.getInputStream()或request.getReader()获取到请求内容后,无法再调request.getParameter()获取请求内容。即对该类型的请求,三个方法互斥,只能调其中一个。
3. request.getParameter()和request.getInputstream()都会从输入流读取数据(流只能读一次),request.getParameter()可以多次重复使用的原因是此方法将request的输入流数据封装到map中去了,所以可以重复获取。
4. request.getParameter()和request.getInputstream()两个方法之间是互斥的,原因是流是不能重复读取的。而不仅request.getInputstream()会读取request的inputstream,request.getParameter()方法内部也会读取request的inputstream。
对于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里面的这三个方法,把数据保持住,后面可以随便使,要修改兼容的方法很多,风险比较大,当然这也违背了最初的设计初衷;
但是当content-type为非application/x- www-form-urlencoded时,例如multipart/form-data编码时,即使先调用request.getParameter()也得不到数据,所以这时调用request.getParameter()方法对 request.getInputStream()或request.getReader()没有冲突,即使已经调用了 request.getParameter()方法也可以通过调用request.getInputStream()或request.getReader()得 到表单中的数据
5. 当请求消息中的实体内容全部是文本数据,并且在Servlet程序中也需要以文本方式来处理这些内容时,适于使用getReader方法。如果Servlet程序不对他们进行处理,而只是存储到服务器的文件系统或数据库中,这适于使用
getInputStream方法。
6. 对于要处理文件上传的Servlet程序来说,只能调用getInputStream方法返回的ServletInputStream字节流对象去读取实体内容,而不能调用getReader方法。因为从ServletInputStream流对象中读取的数据是每个字节的原始内容,而从BufferedReader流对象中读取的数据是原始的内容按某种编码转换成的字符文本。
参考:
https://blog.csdn.net/JokerLJG/article/details/120406355
https://blog.csdn.net/woaixiaoqun/article/details/84518001
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)