HTTP 通信协议是客户与服务器之间一种提交(请求) 信息与响应信息
(request/respone)的通信协议。在JSP 中,内置对象request 封装了用户提交的信息,
那么该对象调用相应的方法可以获取封装的信息,即使用该对象可以获取用户提交的信
息。
客户通常使用HTML 表单向服务器的某个JSP 页面提交信息,表单的一般格式是:
<FORM method= get | post action= “提交信息的目的地页面”>
提交手段
</FORM>…..
其中<Form>是表单标签,method 取值get 或post。Get 方法和post 方法的主要区别
是:使用get 方法提交的信息会在提交的过程中显示在浏览器的地址栏中,而post 方法
提交的信息不会显示在地址栏中。提交手段包括:通过文本框、列表、文本区等,例如:
<FORM action="tom.jsp" method= “post” >
<INPUT type="text" name="boy" value= “ok” >
<INPUT TYPE="submit" value=" 送出" name= “submit”>
</FORM>
该表单使用post方法向页面tom.jsp 提交信息,提交信息的手段是:在文本框输入信
息,其中默认信息是“ok”;然后点击“送出”按钮向服务器的JSP 页面tom.jsp 提交信
息。
request 对象可以使用getParameter(String s) 方法获取该表单通过text 提交的信息,
比如:
request.getParameter(“boy”);
一、获取客户提交的信息
request 对象获取客户提交信息的最常用的方法是getParameter(String s) 。
在下面的例子2中,Example3_2.jsp 通过表单向自己提交一个正数,然后计算这个数的平方根
Example3_2.jsp:
<%@ page contentType="text/html;charset=GB2312" %>
<HTML>
<BODY bgcolor=cyan><FONT size=1>
<FORM action="Example3_2.jsp" method=post name=form>
<INPUT type="text" name="girl">
<INPUT TYPE="submit" value="Enter" name="submit">
</FORM>
<%String textContent=request.getParameter("girl");
double number=0,r=0;
if(textContent==null)
{textContent="";
}
try{ number=Double.parseDouble(textContent);
if(number>=0)
{r=Math.sqrt(number) ;
out.print("<BR>"+String.valueOf(number)+" 的平方根:");
out.print("<BR>"+String.valueOf(r));
}
else
{out.print("<BR>"+" 请输入一个正数");
}
}
catch(NumberFormatException e)
{out.print("<BR>"+" 请输入数字字符");
}
%>
</FONT>
</BODY>
</HTML>
注:使用request 对象获取信息时要格外小心,在上面的例子中:
String textContent =request.getParameter("girl");
获取提交的字符串信息,并且在下面的代码中使用了这个字符串对象:
number=Doule.parseDoubel(textContent);
那么,JSP 引擎在运行这个JSP 页面生成的字节码文件时,会认为你使用了空对象,因为
在这个字节码被执行时(客户请求页面时),客户可能还没有提交数据,textContent 还
没有被创建。如果你使用了空对象,即还没有创建对象,就使用了该对象,Java 解释器
83
就会提示出现了NullPointerException 异常,当然如果你不使用空对象就不会出现异常。
因此,我们可以象上述例子那样,为了避免在运行时Java 认为我们使用了空对象,
使用如下代码:
String textContent=request.getParameter("girl");
if(textContent==null)
{textContent="";
}
二、处理汉字信息
当用request 对象获取客户提交的汉字字符时,会出现乱码问题,所以对含有汉字字
符的信息必须进行特殊的处理方式。首先,将获取的字符串用ISO-8859-1 进行编码,并
将编码存放到一个字节数组中,然后再将这个数组转化为字符串对象即可。如下列所示:
String str=request.getParameter("girl");
byte b[]=str.getBytes( “ISO-8859-1”);
str=new String(b);
通过上述过程,提交的任何信息(无论是汉字字符或西欧字符)都能正确的显示。
下面的例子3 对例子1 按上述办法做了改动,并将按钮上的字变成汉语,在文本框里
输入:“苹果:apple:12 斤5$”,然后提交给tree.jsp。
例子 3 (如图3.3 所示)
Example3_3.jsp:
<%@ page contentType="text/html;charset=GB2312" %>
<HTML>
<BODY bgcolor=green><FONT size=1>
<FORM action="tree.jsp" method=post name=form>
<INPUT type="text" name="boy">
<INPUT TYPE="submit" value=" 提交" name="submit">
</FORM>
</FONT>
</BODY>
</HTML>
tree.jsp:
<%@ page contentType="text/html;charset=GB2312" %>
<MHML>
<BODY>
<P>获取文本框提交的信息:
<%String textContent=request.getParameter("boy");
byte b[]=textContent.getBytes("ISO-8859-1");
textContent=new String(b);
%>
<BR>
<%=textContent%>
<P> 获取按钮的名字:
<%String buttonName=request.getParameter("submit");
byte c[]=buttonName.getBytes("ISO-8859-1");
buttonName=new String(c);
%>
<BR>
<%=buttonName%>
</BODY>
</HTML>
三、常用方法举例
当客户访问一个页面时,会提交一个HTTP 请求给服务器的JSP 引擎,这个请求包
括一个请求行、http头和信息体,如下列:
post/tree2.jsp/HTTP.1.1
host: localhost :8080
accept-encoding :gzip, deflate
其中首行叫请求行,规定了向访问的页面请求提交信息的方式,如,post、 get 等方
式,以及请求的页面的文件名字和使用的通信协议。
第 2、3 行分别是两个头(Header),称host、accept-encoding 是头名字,而localhost:8080
以及gzip,deflate 分别是它们的值。这里host 的值是tree2.jsp 的地址。上面的请求有2
个头:host 和accept-encoding,一个典型的请求通常包含很多的头,有些头是标准的,
有些和特定的浏览器有关。
一个请求还包含信息体,即HTML 标记组成的部分,可能包括各式各样用于提交信
息的表单等,如:
<BODY>
<FORM action="tree2.jsp" method=post name=form>
<INPUT type="text" name="boy">
<INPUT TYPE="submit" value="" name="submit">
</FORM>
</BODY>
我们可以使用JSP 引擎的内置对象request 对象来获取客户提交的信息,说明如下:
1. getProtocol() 获取客户向服务器提交信息所使用的通信协议,比如http/1.1
等。
2. getServletPath() 获取客户请求的JSP 页面文件的目录。
3. getContentLength() 获取客户提交的整个信息的长度。
4. getMethod() 获取客户提交信息的方式,比如:post 或get.
5. getHeader(String s) 获取HTTP 头文件中由参数s指定的头名字的值,一般来
说s参数可取的头名有:accept、 referer 、 accept-language 、content-type、
accept-encoding、 user-agent 、host、 content-length 、 connection 、cookie 等,
比如,s 取值user-agent将获取客户的浏览器的版本号等信息。
6. getHeaderNames() 获取头名字的一个枚举
7. getHeaders(String s) 获取头文件中指定头名字的全部值的一个枚举
8. getRemoteAddr() 获取客户的IP 地址。
9. getRemoteHost() 获取客户机的名称(如果获取不到,就获取IP 地址)。
10. getServerName() 获取服务器的名称。
11. getServerPort() 获取服务器的端口号。
12. getParameterNames() 获取客户提交的信息体部分中name 参数值的一个枚
举。
下面的例子4 使用了request 的一些常用方法。
例子 4(如图3.4、3.5 所示)
Example3_4.jsp:
<HTML>
<BODY bgcolor=cyan><FONT size=1>
<%@ page contentType="text/html;charset=GB2312" %>
<FORM action="tree2.jsp" method=post name=form>
<INPUT type="text" name="boy">
<INPUT TYPE="submit" value="enter" name="submit">
</FORM>
</FONT>
</BODY>
</HTML>
tree2.jsp:
<%@ page contentType="text/html;charset=GB2312" %>
<%@ page import="java.util.*" %>
<MHML>
<BODY bgcolor=cyan>
<Font size=1 >
<BR>客户使用的协议是:
<% String protocol=request.getProtocol();
out.println(protocol);
%>
<BR>获取接受客户提交信息的页面:
<% String path=request.getServletPath();
out.println(path);
%>
<BR>接受客户提交信息的长度:
<% int length=request.getContentLength();
out.println(length);
%>
<BR>客户提交信息的方式:
<% String method=request.getMethod();
out.println(method);
%>
<BR>获取HTTP 头文件中User-Agent 的值::
<% String header1=request.getHeader("User-Agent");
out.println(header1);
%>
<BR>获取HTTP 头文件中accept 的值:
<% String header2=request.getHeader("accept");
out.println(header2);
%>
<BR>获取HTTP 头文件中Host 的值:
<% String header3=request.getHeader("Host");
out.println(header3);
%>
<BR>获取HTTP 头文件中accept-encoding 的值:
<% String header4=request.getHeader("accept-encoding");
out.println(header4);
%>
<BR>获取客户的IP 地址:
<% String IP=request.getRemoteAddr();
out.println(IP);
%>
<BR>获取客户机的名称:
<% String clientName=request.getRemoteHost();
out.println(clientName);
%>
<BR>获取服务器的名称:
<% String serverName=request.getServerName();
out.println(serverName);
%>
<BR>获取服务器的端口号:
<% int serverPort=request.getServerPort();
out.println(serverPort);
%>
<BR>获取客户端提交的所有参数的名字:
<% Enumeration enum=request.getParameterNames();
while(enum.hasMoreElements())
{String s=(String)enum.nextElement();
out.println(s);
}
%>
<BR>获取头名字的一个枚举:
<% Enumeration enum_headed=request.getHeaderNames();
while(enum_headed.hasMoreElements())
{String s=(String)enum_headed.nextElement();
out.println(s);
}
%>
<BR>获取头文件中指定头名字的全部值的一个枚举:
<% Enumeration enum_headedValues=request.getHeaders("cookie");
while(enum_headedValues.hasMoreElements())
{String s=(String)enum_headedValues.nextElement();
out.println(s);
}
%>
<BR>
<P> 文本框text 提交的信息:
<%String str=request.getParameter("boy");
byte b[]=str.getBytes("ISO-8859-1");
str=new String(b);
%>
<BR>
<%=str%>
<BR> 按钮的名字:
<%String buttonName=request.getParameter("submit");
byte c[]=buttonName.getBytes("ISO-8859-1");
buttonName=new String(c);
%>
<BR>
<%=buttonName%>
</Font>
</BODY>
</HTML>
散列表是使用相关关键字查找被存储的数据项的一种数据结构,关键字不可以发生逻辑冲突,即不要两个数据项使用相同的关键字。
散列表在它需要更多的存储空间时会自动增大容量。例如,如果散列表的装载因子是0.75,
那么当散列表的容量被使用了75%时,它就把容量增加到原始容量的2倍。对于数组和
链表这两种数据结构,如果要查找它们存储的某个特定的元素却不知道它的位置,就需
要从头开始访问元素直到找到匹配的为止,如果数据结构中包含很多的元素,就会浪费
时间。这时最好使用散列表来存储要查找的数据。