getInputStream 方法用于返回的一个代表实体内容的输入流对象,其类型为javax.servlet.ServletInputStream。

getReader方法用于返回的一个代表实体内容的BufferedReader对象,返回的BufferedReader对象将实体内容中的字节数据按照请求消息中指定的字符集编码转换成文本字符串。

在调用getReader方法之前,可以调用ServletRequest的setCharacterEncoding方法指定其返回的BufferedReader对象所使用的字符集编码。

使用ServletInputStream对象读取文本格式的实体内容

分析文件上传的请求消息结构

ServletInputStream sis = request.getInputStream();

String filePath = getServletContext().getRealPath("/body.out");

FileOutputStream fos = new FileOutputStream(filePath);

byte[] buf = new byte[1024];

int len = sis.read(buf,0,1024);

while(len != -1)

{

fos.write(buf,0,len);

len = sis.read(buf,0,1024);

}

fos.close();

sis.close();

存储在ServletRequest对象中的对象称之为请求域属性,属于同一个请求的多个处理模块之间可以通过请求域属性来传递对象数据。

与请求域属性相关的方法:

setAttribute方法

getAttribute方法

removeAttribute方法

getAttributeNames方法

请求域属性的典型应用

MVC设计模式将一次请求的响应过程分成三个功能模块(一般称之为层)来协同完成,这三个模块分别是Model(模型层)、View(视图层)、Controller(控制层)。

Model是可作为JavaBean使用的业务对象;View是负责创建显示界面的JSP页面;Controller通常是一个接收用户请求的Servlet程序,它根据请求创建相应的model对象和调用model对象的业务方法,最后再选择一个View去创建网页文档内容并回送给客户端。

Controller调用RequestDispatcher.forward方法将请求转发给作为View的JSP页面,同时将Model对象作为请求域属性传递过去,作为View的JSP页面再从请求域中检索出Model对象。

getParameter方法的中文问题

getParameter等方法在读取的参数信息时,需要进行URL解码。

对于HTTP请求消息的请求行中的URL地址后的参数,getParameter等方法进行URL解码时所采用的字符集编码在Servlet规范中没有明确规定Tomcat中的ServletRequest对象的getParameter等方法默认采用ISO8859-1字符集编码进行URL解码,因此无法返回正确的中文参数信息 。

对于POST方式下的“application/x-www-form-urlencoded”编码格式的实体内容,getParameter等方法以ServletRequest对象的getCharacterEncoding()方法返回的字符集编码对其进行URL解码。

getCharacterEncoding()方法的返回值通常为null,对于这种情况,ServletRequest对象的getParameter等方法将使用默认的ISO8859-1字符集编码对实体内容中的参数进行URL解码,因此也将无法返回正确的中文参数信息。

ServletRequest接口中定义了一个setCharacterEncoding方法来设置请求消息中的实体内容的字符集编码名称,getParameter方法将以该方法设置的字符集编码对实体内容进行URL解码。

setCharacterEncoding方法设置的是请求消息中的实体内容的字符集编码名称,它只影响getParameter方法对POST方式下的“application/x-www-form-urlencoded”编码格式的实体内容进行URL解码的结果,而不能影响getParameter方法对HTTP请求消息的请求行中的URL地址后的参数进行URL解码的结果。

一些参考经验

如果提交FORM表单的页面与处理表单请求的Servlet程序都是由同一个人或同一个项目组开发的,那么只要在处理表单提交的Servlet程序中将传递给setCharacterEncoding方法的字符集编码设置为该表单所在页面的字符集编码即可。

如果Servlet程序可以接收来自多个其他站点的FORM表单提交的数据,而每个其他站点的页面所采用的字符集编码可能各不一样,要想让Servlet程序知道FORM表单内容的字符集编码,可以在FORM表单中增加一个隐藏字段来传递当前FORM内容的字符集编码名称。

只要超链接、FORM表单的action属性设置、请求转发和重定向的URL等任何一种请求路径中要包含参数,就必须对参数部分进行URL编码。对参数进行URL编码时所选择的字符集编码应尽量与当前页面的字符集编码保持一致,也可以用一个参数来指定URL编码内容的字符集编码名称。

所有标准的浏览器和客户机终端都支持UTF-8编码,如果WEB服务器要能兼容处理各个国家和地区版本的浏览器所传递的FORM表单信息,网页文档应当使用UTF-8编码格式。

在编写应用程序时应该注意一些隐性的字符编码错误。有些程序在输出时有编码转换错误,在读取输入时返回的字符串也有转换错误,当该程序输出它所读取到的有问题的字符串时,显示的结果可能是正常的中文字符。

摘自 宋利兴的专栏

getInputStream与getReader方法的更多相关文章

  1. getParameter() getInputStream()和getReader() 区别 这三种方法是有冲突的,因为流只能被读一次。

    我们经常用servlet和jsp, 经常用request.getParameter() 来得到数据. request.getParameter()request.getInputStream()req ...

  2. 获取【请求体】数据的3种方式(精)(文末代码) request.getInputStream() request.getInputStream() request.getReader()

    application/x- www-form-urlencoded是Post请求默认的请求体内容类型,也是form表单默认的类型.Servlet API规范中对该类型的请求内容提供了request. ...

  3. getParameter() getInputStream()和getReader() 区别

    我们经常用servlet和jsp, 经常用request.getParameter() 来得到数据. request.getParameter() request.getInputStream() r ...

  4. SERVLET类常用接口及方法

    SERVLET类常用接口及方法 2011-09-09 16:14:43    [size=xx-small]SERVLET类常用接口及方法2007年04月05日 星期四 04:46 P.M.基本类和接 ...

  5. JavaWeb chapter 4 Servlet处理HTTP请求

    1.  GET/POST提交方法: 用户在网页上点击一个超链接:(get) 用户提交在网页上提交表单:(post或者get) 用户在浏览器地址栏输入URL地址并回车(get) 2.  默认情况下都是使 ...

  6. java Servlet接口及应用

    基本类和接口 一.javax.servlet.Servlet接口 servlet抽象集是javax.servlet.Servlet接口,它规定了必须由Servlet类实现由servlet引擎识别和管理 ...

  7. Servlet API中文版

    基本类和接口 一.javax.servlet.Servlet接口 servlet抽象集是javax.servlet.Servlet接口,它规定了必须由Servlet类实现由servlet引擎识别和管理 ...

  8. java Servlet接口及应用(转)

    基本类和接口 一.javax.servlet.Servlet接口 servlet抽象集是javax.servlet.Servlet接口,它规定了必须由Servlet类实现由servlet引擎识别和管理 ...

  9. SpringMVC 控制器默认支持GET和POST两种方式

    在SpringMVC的controller中,@RequestMapping只写路径,不包含RequetMethod.GET和RequetMethod.POST,HttpServletRequest的 ...

随机推荐

  1. 用APK Downloader直接从Google Play上下载apk

    APK Downloader可以直接从Google Play上下载apk,相比较其他软件,这个不需要提供Google ID,对于没有刷机的同学还是有些帮助的.

  2. Quartz定时任务学习(九)Quartz监听器

    Quartz 提供了三种类型的监听器:监听 Job 的,监听 Trigger 的,和监听 Scheduler 自已的. 本章解释如何应用每一种类型来更好的管理你的 Quartz 应用,并获悉到什么事件 ...

  3. WPF button 圆角制作

    将以下节点复制到app.xaml的<Application.Resources>节点下 <Style TargetType="{x:Type Button}"&g ...

  4. MVC-@html.ActionLink的几种参数格式

    一 Html.ActionLink("linkText","actionName") 该重载的第一个参数是该链接要显示的文字,第二个参数是对应的控制器的方法, ...

  5. <s:form action="login"...与<s:form action = "login.action".的区别

    1.<s:form action="login" namespace="/login"> 它表示的是<form id="login& ...

  6. POJ 1185 状态压缩DP 炮兵阵地

    题目直达车:   POJ 1185 炮兵阵地 分析: 列( <=10 )的数据比较小, 一般会想到状压DP. Ⅰ.如果一行10全个‘P’,满足题意的状态不超过60种(可手动枚举). Ⅱ.用DFS ...

  7. 再谈内存管理与ARC运行机制(一)

    内存管理 内存在Objective-C开发中是一种相对稀缺的资源,拿Iphone4为例,它的内存只有512mb,所以妥善的处理好所创造,所使用的每个对象与变量都将成为一个问题.在ARC出现以前,同大部 ...

  8. Android开发之手势滑动(滑动手势监听)详解

    Android开发之手势滑动(滑动手势监听)详解 在Android应用中,经常需要手势滑动操作,比如上下滑动,或左右方向滑动,处理手势滑动通常有两种方法:一种是单独实现setOnTouchListen ...

  9. Android开发之显示进度对话框

    一般有两种对话框,一个是普通的简单的please wait对话框,另一种是创建显示操作进度(如下载状态)的对话框. 第一种普通的效果图如下: 第一种普通的实现代码: public void onCli ...

  10. 解决iScroll中事件点击一次却触发两次的问题

    var t1=null;//全局 function myClick() { if (t1 == null){ t1 = new Date().getTime(); }else{ var t2 = ne ...