一、ServletRequest接口
HttpServletRequest接口继承了ServletRequest接口,实现类通常代表一个实际的Http Request。
Servlet容器负责创建一个HttpServletRequest对象(在Web服务器接收到浏览器的一个请求后),然后Servlet容器把这个HttpServletRequest传递给相关Servlet的service方法。(其实同时创建和传递的还有HttpServletResponse对象,这也是我们在编写相关Servlet时,无须关注request是如何被接收,也无须关注response最终如何被返回,这些都是Servlet容器和Web服务器的职责)
ServletRequest接口,定义了一个能代表实际request的对象,它包含了这个request的各项信息。
一个ServletRequest对象提供的数据包括了parameter name and value,attributes,以及input stream。HttpServletRequest对象还能提供额外的http协议相关的信息(他是唯一的子接口)。
当然接口只是定义了行为规范,Java为其提供了两个基础的实现,以供开发人员扩展:
HttpServletRequestWrapper, ServletRequestWrapper。
二、Request中的parameter 和 attributes
2.1 首先来个大体的区分
Request parameter是客户端提交过来的参数,以“name=value”的字符串形式存储在Request对象中,所以对于parameter,只有getParameter方法。
例如,我们登录时提交账户信息,假如是GET方法提交(实际上不会用GET提交),那么在提交的信息会以"?username=root&password=123456"这种形式附加在表单指向的url后面,这种形式称之为Query String。而POST方式则会把信息放在Request Body当中,这种形式称之为POST Body。
StackOverFlow
一个有意思的点是,Query string data is presented(显示) BEFORE post body data.
例如,如果使用Query String提交“a=hello”和POST Body提交“a=goodbye“和”a=world”,则结果参数集将被排序为a=(hello, goodbye, world)。
更新:发现我以前讲得不够清楚。可以参考下列网址:
How are parameters sent in an HTTP POST request?
HTTP中application/x-www-form-urlencoded字符说明
四种常见的 POST 提交数据方式
在将post表单数据填充到参数集(parameter set)之前,必须满足以下条件:
The request is an HTTP or HTTPS request.
The HTTP method is POST.
The content type is application/x-www-form-urlencoded.
The servlet has made an initial call of any of the \'getParameter\' family of methods on the request object.
如果不满足条件,且post表单数据不包含在参数集中,post数据仍然可以通过request object的输入流提供给servlet。
如果满足这些条件,post表单数据将不再可以直接从请求对象的输入流中读取。
Request attributes则与客户端无关,服务器端接收后产生的一个Request对象,可能在各个不同的Servlet间传递而进行必要的处理,这时我们可以在Servlet A中通过setAttribute(String name,Object)方法存储一些信息,然后在Servlet B中通过getAttribute(String name)方法,取出相关的Object对象,进行一些处理。
API中提到了一点,Attributes are reset between requests,我有点疑惑为什么要特意提这样一句,直观上来说,在不同的Request对象上存储东西,二者当然不会共享吧?所以对Attributes的存储机制开始好奇了。
An attribute is a server variable that exists within a specified scope i.e.:
application, available for the life of the entire application
session, available for the life of the session
request, only available for the life of the request
page (JSP only), available for the current JSP page only
可以确定的一点是,当代码中出现了setAttribute()方法时,那么这个Request对象必定会与一个RequestDispatcher对象一起工作了,因为你在此处添加了一些有用的数据,肯定要在别处取出来用吧?
2.2 RequestDispatcher接口
先总结,RequestDispatcher接口类用于request的转发。
RequestDispatcher也是一个接口,它定义一个这样的对象:接收来自客户端的request,然后把他们送到服务器的其他资源上去(如servlet,html文件,JSP文件)。所以,通常是Servlet容器创建RequestDispatcher对象,用于包装一个有特定路径或者名称的服务器端资源。
这个接口用于包装servlet,但是servlet容器可以创建RequestDispatcher对象来包装任何类型的资源。