一、request对象
HTTP能仁协议是客户与服务器之间一种提交(请求)信息与响应信息(request/response)的通信协议。在JSP中,内置对象request封装了用户提交的信息,那么该对象调用相应的方法可以获取封装的信息,即使用该对象可以获取用户提交的信息。
客户通常使用HTML表单向服务器的某个JSP页面提交信息,表单的一般格式是:
<FORM method=get | post action="提交信息的目的地页面">
提交手段
</FORM>
get与post的主要区别是:使用get方法提交的信息会在提交的过程中显示在浏览器的地址栏中,而使用post方法提交的信息不会显示在地址栏中,提交手段包括通过文本框、列表、文本区等。
request对象可以使用getParameter(String s)方法获取该表单通过text提交的信息。如:
request.getParameter("abc");
使用request对象获取信息时要格外小心。举例说,如果通过String textContent = request.getParameter("girl");获取提交的字符串信息,并且在number = Double.parseDouble(textContent);这样的代码中使用了这个字符串对象。那么,JSP引擎在运行这个JSP页面生成的字节码文件时,会认为你使用了空对象,因为在这个字节码被执行时(客户请求页面时),客户可能还没有提交数据,textContent也还没有被创建。如果你使用了空对象,即还没有创建对象,就使用了该对象,JAVA解释器会提示出现了NullPointerException异常,当然如果你不使用空对象就不会出现异常。因为我们为了避免在字节码文件运行时JAVA认为我们使用空对象,可以使用以下代码:
if(textContent == null)
{
textContent = "";
}
当用request对象获取客户提交的汉字字符时,会出现乱码问题,所以对含有汉字字符的信息必须进行特殊的处理。首先,将获取的字符串用ISO-8859-1进行编码,并将编码存放到一个字节数组中,然后再将这个数组转化为字符串对象即可。这样,提交的任何信息(无论是汉字字符或西欧字符)都能正确地显示。
常用方法举例
当客户访问一个页面时,会提交一个HTTP请求给服务器的JSP引擎,这个请求包括一个请求行,HTTP头和信息体,如下例:
post/tree2.jsp/HTTP.1.1
host:localhost:8080
accep-encoding: gzip, deflate
其中首行叫请求行,规定了向访问的页面请求提交信息的方式,如post 、get等方式,以及请求的页面的文件名字和使用的通信协议。第2、3行分别是两个头(Header),host和accept-encoding是头名字,而localhost:8080和gzip,deflate分别是它们的值。这里host的值是tree2.jsp的地址。上面的请求有两个头,一个典型的请求通常包含很多的头,有些头是标准的,有些头和特定的浏览器有关。一个请求还包含信息体,即HTML标记组成的部分,可能包括各式各样用于提交信息的表单等。如:
<FORM action="tree2.jsp" method=post name=form>
<INPUT type="text" name="boy">
<INPUT type="submit" value="" name="submit">
</FORM>
我们可以使用JSP引擎内置对象request对象来获取客户提交的信息。说明如下:
getProtocol() |
获取客户向服务器提交信息所使用的通信协议。如:http/1.1 |
getServletPath() |
获取客户请求的JSP页面文件的目录 |
getContentLength() |
获取客户提交的整个信息的长度 |
getMethod() |
获取客户提交信息的方式。如:post或get |
getHeader(String s) |
获取HTTP头文件中由参数s指定的头名字的值。一般来说s可取的头名有accept、referer、accept-language、content-type、accept-encoding、user-agent、host、content-length、connection、cookie等 |
getHeaderNames() |
获取头名字的一个枚举 |
getHeaders(String s) |
获取头文件中指定头名字的全部值的一个枚举 |
getRemoteAddr() |
获取客户的IP地址 |
getRemoteHost() |
获取客户机的名称(如果获取不到,就获取IP地址) |
getServerName() |
获取服务器的名称 |
getServerPort() |
获取服务器的端口号 |
getParameterNames() |
获取客户提交的信息体部分中name参数值的一个枚举。 |
散列表
散列表是使用相关关键字查找被存储的数据项的一种数据结构,关键字不可以发生逻辑冲突,即不能两个数据项使用相同的关键字。散列表在它需要更多的存储空间时会自动增大容量。例如:如果散列表的装载因子是0.75,那么当散列表的容量被使用了75%时,它就把容量增加到原始容量的2倍。对于数组和链表这两种数据结构,如果要查找它们存储的某个特定的元素却不知道它的位置,就需要从头开始访问元素起到找到匹配为止。如果数据结构中包含很多的元素,就会浪费时间,这时最好使用散列表来存储要查找的数据。
可用于用户注册,用户通过提交姓名实现注册,当request对象获取姓名信息后,首先检查散列表对象中是否已经存在这个名字,该散列表存储了已经注册的用户的名字。如果目前准备注册的用户提交的名字在散列表中已经存在,就提示用户更换名字。
获取HTML表单提交的数据
表单的一般格式:
<FORM method=get | post action="提交信息的目的地页面" name="表单的名字">
数据提交手段部分
</FORM>
<FORM>是表单标签。一个表单的数据提交手段部分经常包括如下的标记符号:
■<INPUT...>
■<Select...></Select>
■<Option...></Option>
■<TextArea...></TextArea>
<INPUT>的基本格式
在表单中用input标记来指定表单中数据输入方式以及表单的提交键。input标记中的type属性可以指定输入方式的GUI对象,name属性用来指定这上GUI对象的名称。服务器通过name属性指定的名字来获取“输入对象的GUI类型”中提交的数据。“输入对象的GUI类型”可以是:
■文本框:text :当输入对象的GUI类型是text时,除了用name为text指定名字外,还可以为text指定其他的一些值,
如value(初始值),size(对象的长度,单位是字符),algin(对齐方式),maxlength(可输入字符
的最大长度)等。
■单行框:radio:当输入对象的GUI类型是radio时,除了用name为radio指定名字外,还可以为radio指定其他的一
些值,如value(指定radio的值),algin(对齐方式),checked等。如果几个单选框的name取值相
同,那么同一时刻只能有一个被选中。服务器通过name指定的名字来获取被选中的radio提交的由
value指定的值。checked如果取值是一个非空字符串,那么该单选框的初始状态就是选中状态。
■复选框:checkbox:当输入对象的GUI类型是checkbox时,除了用name为checkbox指定名字外,还可以为
checkbox指定其他的一些值。如value(checkbox的值),algin,checked等。复选框与单选框
的区别就是可以多选。服务器通过name指定的名字来获取被选中的checkbox提交的由value
指定的值。为了使服务器能获取提交的值,复选框name的值应互不相同。checked如果取值
是一个非空的字符串,那么该复选框的初始状态就是选中状态。
■口令框:password:它是输入口令的特殊文本框,输入的信息用“*”回显,防止他人偷看口令。服务器通过
name指定的字符串获取password提交的值。你在口令框中输入AAA,那么AAA将被提交给服
务器。口令框仅仅起着不让别人偷看的作用,不提供保密措施。
■提交键:submit:为了能把表单的数据提交给服务器,一个表单至少要包含一个提交键。单击提交键后,服务器就
可以获取表单提交的各个数据。当然服务器也可以获取提交键的值,服务器通过name指定的名
字来获取提交键提交的由value指定的值。
■重置键:reset:重置键将表单中输入的数据清空,以便重新输入数据。
<Select><Option>格式
下拉式列表和滚动列表通过<Select>和<Option>标记来定义。基本格式为:
<Select>
<Option>
<Option>
...
</Select>
下拉列表:<Select name="shulie">
<Option value="cat">你选了小猫
<Option value="dog">你选了小狗
</Select>
服务器通过name获取下拉列表中被选中的Option的值(参数value指定的值)。
滚动列表:<Select name="shulie" size=2>
<Option value="1">计算1到n的连续和
<Option value="2">计算1到n的平方和
<Option value="2">计算1到n的立方和
</Select>
在Select中增加size属性的值就变成滚动列表,size的值是滚动列表的可见行的个数。服务器通过name获取下拉列表中被选中的Option的值(参数value指定的值)。
<TextArea>格式
<TextArea>标记在表单中指定一个能输入多行文本的文本区域。如:
<TextArea name="ilovethisgame" Rows="4" Cols="20"></TextArea>
表格
表格由<Table></Table>标记定义。一般格式:
<Table>
<TR width="该行的宽度">
<TH width="单元格的宽度">单元格中的数据</TH>
...
<TD width="单元格的宽度">单元格中的数据</TD>
...
</TR>
...
</Table>
其中<TR>与</TR>之间定义表格的一个行,<TH>和<TD>标记定义这一行中的表格单元,二者的区别是:<TH>定义的单元着重显示,<TD>称作普通单元,不着重显示。一行中的着重单元和普通单元可以交替出现,也可以全是着重单元或普通单元。<Table>中增加选项Border可指明该表格是否带有边框。
二、response对象
当客户访问一个服务器的页面时,会提交一个HTTP请求,服务器收到请求时,返回HTTP响应。响应和请求类似,也有某种结构。每个响应都由状态行开始,可以包含几个头及可能的信息体(网页的结果输出部分)。可以用response对象对客户的请求做出动态响应,向客户端发送数据。比如,当一个客户请求访问一个JSP页面时,该页面用page指令设置页面的contentType属性的值是text/html那么JSP引擎将按照这种属性值响应客户对页面的请求,将页面的静态部分返回给客户,如果想动态地改变contentType的属性值就需要用response对象改变页面的这个属性的值,做出动态的响应。
动态响应contentType属性
当一个客户请求访问一个JSP页面时,如果该页面用page指令设置页面的contentType属性的值是text/html,那么JSP引擎将按着这种属性值做出响应,将页面的静态部分返回给客户。由于page指令只能为contentType属性指定一个值来决定响应的MIME类型,如果想动态地改变这个属性的值来响应客户,就需要使用response对象的setContentType(String s)方法来实现:
public void setContentType(String s)
该方法动态设置响应的MIME类型,参数s可取text/html、text/plain、application/x-msex-cel、application/msword等。当服务器用setContentType方法动态改变了contentType的属性值,即响应的MIME类型,并将JSP页面的输出结果按照新的MIME类型返回给客户时,客户端要保证支持这种新的MIME类型。客户如果想知道自己浏览器能支持哪些MIME类型,可以单击“资源管理器”—“工具”—“文件夹选项”—“文件类型”
response的HTTP文件头
当客户访问一个页面时,会提交一个HTTP头给服务器,这个请求包括一个请求行、HTTP头和信息体。同样,响应也包括一些头。response对象可以使用方法
addHeader(String head,String value);
或者方法
setHeader(String head,String value);
动态添加新的响应头和头的值,并将这些头发送给客户的浏览器。如果添加的头已经存在,则先前的头被覆盖。
response重定向
在某些情况下,当响应客户时,需要将客户重新引导至另一个页面。例如,如果客户输入的表单信息不完整,就会再次被引导到该表单的输入页面。可以使用response对象的sendRedirect(URL url)方法实现客户的重定向。
response的状态行
当服务器对客户请求进行响应时,它发送的首行称作状态行。状态行包括3位数字的状态代码和对状态代码的描述(称做原因短语)。以下是5类状态代码的大概描述:
1yy:(1开头的3位数):主要是实验性质的。
2yy:用来表明请求成功。例如,状态代码200可以表明已成功取得了请求的页面。
3yy:用来表明在请求满足之前应采取进一步的行动。
4yy:当浏览器做出无法满足的请求时,返回该状态代码。例如404表示请求的页面不存在。
5yy:用来表示服务器出现问题。例如500说明服务器内部发生错误。
一般不需要修改状态行,在出现问题时,服务器会自动响应,发送相应的状态代码。我们也可以使用response对象的setStatus(int n)方法来增加状态行的内容。
状态代码表
状态代码 |
代码说明 |
101 |
服务器正在升级协议 |
100 |
客户可以继续 |
201 |
请求成功且在服务器上创建了新的资源 |
202 |
请求已被接受但还没有处理完毕 |
200 |
请求成功 |
203 |
客户端给出的原信息不是发自服务器的 |
204 |
请求成功,但没有新信息 |
205 |
客户必须重置文档视图 |
206 |
服务器执行了部分get请求 |
300 |
请求的资源有多种表示法 |
301 |
资源已经被永久移动到新位置 |
302 |
资源已经被临时移动到新位置 |
303 |
应答可以在另外一个URL中找到 |
304 |
get方式请求不可用 |
305 |
请求必须通过代理来访问 |
400 |
请求有语法错误 |
401 |
请求需要HTTP认证 |
403 |
取得了请求但拒绝服务 |
404 |
请求的资源不可用 |
405 |
请求所用的方法是不允许的 |
406 |
请求的资源只能用请求不能接受的内容特性来响应 |
407 |
客户必须得到认证 |
408 |
请求超时 |
409 |
发生冲突,请求不能完成 |
410 |
请求的资源已经不可用 |
411 |
请求需要一个定义的内容长度才能处理 |
413 |
请求太大,被拒绝 |
414 |
请求的URL太大 |
415 |
请求的格式被拒绝 |
500 |
服务器发生内部错误,不能服务 |
501 |
不支持请求的部分功能 |
502 |
从代理和网关接受了不合法的字符 |
503 |
HTTP服务暂时不可用 |
504 |
服务器在等待代理服务器应答时发生超时 |
505 |
不支持请求的HTTP版本 |
三、session对象
HTTP协议是一种无状态协议。一个客户向服务器发生请求(request),然后服务器返回响应(response),连接就被关闭了。在服务器端不保留连接的有关信息,因此当下一次连接时,服务器已没有以前的连接信息了,无法判断这一次连接和以前的连接是否属于同一客户。因此,必须使用会话记录有关连接的信息。
从一个客户撕开浏览器连接到服务器的某个服务目录,到客户关闭浏览器离开服务称做一个会话。当一个客户访问一个服务器时,可能会在某个服务目录中反复链接几个页面、反复刷新一个页面或不断地向一个页面提交信息等,服务器应当通过某种办法知道这是同一个客户,这就需要session(会话)对象。
session对象的Id
当一个客户首次访问服务目录中的一个JSP页面时,JSP引擎产生一个session对象。这个session对象调用相应的方法可以存储客户在访问各个页面期间提交的各种信息。比如姓名、号码等信息。这个session对象被分配了一个String类型的Id号,JSP引擎同时将这个Id号发送到客户端,存放在客户的Cookie中。这样,session对象和客户之间就建立起一一对应的关系,即每个客户都对应着一个session对象(该客户的会话),不同用户的session对象互不相同,具有不同的Id号码。JSP引擎为每个客户启动一个线程,也就是说,JSP为每个线程分配不同的session对象。当客户再访问链接该服务目录的其他页面时,或从该服务目录连接到其他服务器再回到该服务目录时,JSP引擎不再分配给客户新的session对象,而是使用完全相同的一个,起到客户关闭浏览器或这个session对象达到了最大生存时间,服务器端该客户的session对象被取消,和客户的会话对应关系消失。当客户重新打开浏览器再连接到该服务目录时,服务器为该客户再创建一个新的session对象。
注:同一个客户在不同服务目录中的session是互不相同的。
session对象与URL重写
session对象是否能和客户建立起一一对应关系依赖于客户的浏览器是否支持cookie。如果客户端不支持cookie,那么客户在不同网页之间的session对象可能是互不相同的,因为如果服务器无法将Id存放到客户端,就不能建立session对象和客户的一一对应关系。将浏览器的cookie设置为禁止后,访问不同的页面会有不同的Id号。也就是说,同一客户对应了多个session对象,这样服务器就无法知道在这些页面上访问的实际上是同一个客户。
如果客户的浏览器不支持cookie,可以通过URL重写来实现session对象的惟一性。所谓URL重写,就是当客户从一个页面重新链接到另一个页面时,通过向这个新的URL添加参数,把session对象的Id传带过去,这样就可以保障客户在该网站各个页面中的session对象是完全相同的。可以使用response对象调用encodeURL()或encodeRedirectURL()方法实现URL重写。比如,从tom.jsp页面链接到jerry页面,首先实现URL重写,
String str = response.encodeRedirectURL("jerry.jsp");
然后将连接目标写成<%=str%>
session对象的常用方法
public void setAttribute(String key, Object obj) |
session对象类似于散列表,可以调用该方法将参数Object指定的对象obj添加到session对象中,并为添加的对象指定了一个索引关键字。如果添加的两个对象的关键字相同,则先前添加的对象被清除。 |
public Object getAttribute(String key) |
获取session对象中含有的关键字是key的对象。由于任何对象都可以添加到session对象中,因此用该方法取回对象时,应强制转化为原来的类型。 |
public Enumeration getAttributeName() |
session对象调用该方法产生一个枚举对象。该枚举对象使用nextElemets()方法遍历session对象所含有的全部对象。 |
public long getCreationTime() |
session对象调用该方法可以获取该对象创建的时间。单位是毫秒 |
public long getLastAccessedTime() |
获取当前session对象最后一次被操作的时间。单位是毫秒 |
public int getMaxInactiveInterval() |
得到允许session对象处于非活动状态的最长时间。 |
public void setMaxInactiveInterval(int n) |
设置允许session对象处于非活动状态的最长时间,单位是秒 |
public void removeAttribute(String key) |
从当前session对象中删除关键字是key的对象。 |
public String getId() |
获取session对象的编号。 |
invalidate() |
使用session对象无效。 |
四、out对象
out对象是一个输出流,用来向客户端输出数据。out对象可调用如下的方法用于各种数据的输出。例如:
out.print(Boolean);out.println(Boolean); 用于输出一个布尔量
out.print(char);out.println(char); 输出一个字符
out.print(double);out.println(double); 输出一个双精度的浮点数
out.print(float);out.println(float); 用于输出一个单精度的浮点数
out.print(long);out.println(long); 输出一个长整型数据
out.print(String);out.println(String); 输出一个字符串对象的内容
out.newLine(); 输出一个换行符
out.flush(); 输出缓冲区里的内容
out.close(); 关闭流
五、application对象
当一个客户第一次访问服务目录上的一个JSP页面时,JSP引擎创建一个和该客户相对应的session对象,当客户在所访问的服务目录的各个页面之间浏览时,这个session对象都是同一个,直到客户关闭浏览器,这个session对象才被取消,而且不同客户的session对象是互不相同的。与session对象不同的是application对象。服务器启动后,就产生了这个application对象。当一个客户访问服务目录上的一个JSP页面时,JSP引擎为该客户分配这个application对象,当客户在所访问的服务目录的各个页面之间浏览时,这个application对象都是同一个,直到服务器关闭,这个application才被取消。与session对象不同的是,所有客户的application对象是相同的一个,即所有客户共享这个内置的application对象。JSP引擎为每个客户启动一个线程,也就是说,这些线程共享这个application对象。application对象的常用方法:
public void setAttribute(String key,Object obj) |
将参数Object指定的对象obj添加到application对象中,并为添加的对象指定一个索引关键字。如果添加的两个对象的关键字相同,则先前添加的对象被清除。 |
public Object getAttribute(String key) |
获取application对象中含有的关键字是key的对象。由于任何对象都可以添加到application对象中,因此用该方法取回对象时,应强制转化为原来的类型。 |
public Enumeration getAttributeNames() |
产生一个枚举对象。该枚举对象使用nextElemets()方法遍历application对象所含有的全部对象。 |
public void removeAttribute(String key) |
从当前application对象中删除关键字是key的对象。 |
public String getServletinfo() |
获取Servlet编译器的当前版本的信息。 |
由于application对象对所有的客户都是相同的,任何客户对该对象中存储的数据的改变都会影响到其他客户,因此,在某些情况下,对该对象的操作需要实现同步处理。
有些服务器不直接支持application对象,必须先用ServletContext类声明这个对象,再使用getServletContext()方法对这个对象进行初始化。