getParameter()、getInputStream()和getReader() 三者的区别

getParameter()、getInputStream()和getReader() 三者都是从selvlet中request对象得到提交的数据,但是用途不同。要根据 form 表单提交数据的编码方式选择不同的方法。

form表单中enctype 属性规定在发送到服务器之前应该如何对表单数据进行编码。
默认地,表单数据会编码为 “application/x-www-form-urlencoded”。就是说,在发送到服务器之前,所有字符都会进行编码(空格转换为 “+” 加号,特殊符号转换为 ASCII HEX 值)。

描述
application/x-www-form-urlencoded在发送前编码所有字符(默认)
multipart/form-data不对字符编码。在使用包含文件上传控件的表单时,必须使用该值。
text/plain空格转换为 “+” 加号,但不对特殊字符编码。

一.getParameter()

enctype=application/x- www-form-urlencoded
通常使用的表单也是采用这种方式编码的,Servlet 的 API 提供了对这种 编码方式解码的支持,只需要调用 ServletRequest 类中的 getParameter()方法就可以得到用户表单中的字段和数据。但对于传输大块的二进制数据显得力不从心。

二.getInputStream()和getReader()

1)、getInputStream()方法返回一个代表实体内容的输入流对象。
2)、getReader()方法返回一个代表实体内容的BufferedReader对象,实体内容的字节数据按照请求消息中指定的字符集编码转换成文本字符串。

enctype=multipart/form-data表单采用这种编码时,即使先调用request.getParameter()也得不到数据,但是这时调用 request.getParameter()方法对 request.getInputStream()或request.getReader()没有冲突,即使已经调用了 request.getParameter()方法也 可以通过调用request.getInputStream()或request.getReader()得 到表单中的数据,而request.getInputStream()和request.getReader()在同 一个响应中是不能混合使用的,如果混合使用就会抛异常。

1、getReader和getInputStream适用范围。

1.1.当请求消息中的实体内容全部是文本数据,并且Servlet程序也需要以文本方式处理时,适用于getReader方法。如果不处理只是存储到服务器文件系统或者数据库中,应该使用getInputStream。
1.2.处理文件上传,只能用getInputStream返回的ServletInputStream字节流对象读取实体内容,因为他读取的数据是每个字节的原始内容,而从BufferedReader流对象中读取的数据是原始内容按某种编码转换成的字符文本。

2、getReader特别之处

2.1 .在http请求中,有Header和Body之分,读取header使用request.getHeader("…");
2.2.读取Body使用request.getReader(),但getReader获取的是BufferedReader,需要把它转换成字符串,下面是转换的方法。

     String str = "";
      InputStream in = request.getInputStream();  
      InputStreamReader reader = new InputStreamReader(in);  
      BufferedReader bd = new BufferedReader(reader);
      while ((inputLine = bd.readLine()) != null)
       {
          str += inputLine;
                   }

三、注意事项

1.三种方式是冲突的,只能读取一次。混合使用会抛异常。

参考文献链接:
1.https://blog.csdn.net/fanyun7654/article/details/21704355
2.http://www.cnblogs.com/jimmy-muyuan/p/5294654.html

  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
问题中提到了在拦截器或者过滤器中通过getInputStream()读取参数后,在Controller中无法重复读取,会抛出异常。这是因为在HttpServletRequest对象中,getInputStream()和getReader()方法是互斥的,只能调用其中一个来读取请求体的内容。如果在拦截器或过滤器中已经调用了getInputStream()方法读取了参数,那么在Controller中就不能再调用getReader()方法来读取参数,否则会抛出异常。\[1\] 为了解决这个问题,可以在拦截器或过滤器中将请求体的内容保存下来,然后在Controller中直接使用保存的内容来处理。可以使用RequestReadUtils类中的read方法来读取请求体的内容并保存起来,然后在Controller中使用保存的内容来处理。\[3\] 另外,如果请求的Content-Type是application/json,可以使用getReader()方法来获取参数;如果是multipart/form-data,可以直接使用request.getParameter方法来获取参数。\[2\] #### 引用[.reference_title] - *1* [解决HttpServletRequest 流数据不可重复读](https://blog.csdn.net/thulium_kyg/article/details/120004808)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [异常处理:getReader()/getInputStream() has already been called for this request](https://blog.csdn.net/qq_39517116/article/details/116715835)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值