Web浏览器显示表单,读取用户输入,将该输入编码为称为“查询字符串”的标准格式,并将该数据发送给位于Web服务器上的CGI程序。当你写一个与CGI程序交谈的小程序时,你必须自己做所有这些。
首先要知道的是,CGI程序可以通过两种方式接收来自Web浏览器的数据,GET和POST。使用GET的CGI从URL中获取参数。使用POST的程序从标准输入读取它们的参数。
第二件要知道的事情是,当你通过网页浏览器向表单提交数据时,网页浏览器会为你编码数据。然而,在一个applet中,你需要自己编码数据。数据编码如下:每个表单条目是名称 - 值对。名称和值由等号(=)相互分隔。成对(&)彼此分开。例如,考虑这种形式:
<Form method = GET action =“http://metalab.unc.edu/javafaq/cgi-bin/getform.pl”>
电子邮件:<Input NAME =“email”size = 40>
名称:<Input NAME =“realname”size = 40>
<Input TYPE =“submit”VALUE =“订阅”>
</ FORM>
你会发现它使用GET方法与http://metalab.unc.edu/javafaq/cgi-bin/getform.pl中的cgi-bin程序进行通信。它发送两个字段到CGI程序,电子邮件和真实姓名。假设您要发送电子邮件地址字符串“elharo@metalab.unc.edu”,以及真实姓名字符串“Elliotte Harold”。然后查询字符串如下所示:
String qs = "email=elharo%40metalab.unc.edu&realname=Elliotte%20Harold";
“Elliotte Harold”中的空格和“elharo@metalab.unc.edu”中的@已被转换为百分号转义。值中的所有非字母数字字符必须用%替换为ASCII值。因此,空格变成%20,@变成%40。
要将此数据发送到服务器,请将问号(?)和查询字符串附加到CGI程序的URL,并从服务器请求该URL。因此你想要的URL是:
http://metalab.unc.edu/javafaq/cgi-bin/getform.pl?email=elharo%40metalab.unc.edu;realname=Elliotte%20Harold";
用Java语言来说,这需要从这个字符串构造一个URL对象,并打开该URL的InputStream来读取响应。以下代码片段演示:
try {
String thisLine;
String qs = "email=elharo%40metalab.unc.edu&realname=Elliotte%20Harold";
URL u = new URL("http://metalab.unc.edu/javafaq/cgi-bin/getform.pl?" + qs);
DataInputStream theHTML = new DataInputStream(u.openStream());
while ((thisLine = theHTML.readLine()) != null) {
System.out.println(thisLine);
}
}
catch (Exception e) {
System.err.println(e);
}
与使用POST的CGI程序进行通信有点复杂,而且在Java 1.0.2中不能很好地工作。它可能在Java 1.1中得到改进。在发布到CGI时,您完全按照GET请求对查询字符串进行编码。然而,不要只是请求一个URL的InputStream,而是打开一个到CGI程序的URLConnection。
不要像GET那样将查询字符串追加到URL中。相反,将 URLConnection
' doOutput
和' doInput
字段设置AllowUserInteraction
为true并设置为false。链URLConnection
的OutputStream
到DataOutputStream
和使用DataOutputStream
的 writeBytes()
方法查询字符串发送到服务器。
如果你想读的响应,则链URLConnection
的 InputStream
一个DataInputStream
,并且使用DataInputStream
的 readLine()
方法来读取一个响应while
循环。以下代码片段演示:
String query = "email=elharo%40metalab.unc.edu;realname=Elliotte%20Harold";
try {
// open the connection and prepare it to POST
URL u = new URL("http://metalab.unc.edu/javafaq/cgi-bin/postform.pl");
URLConnection uc = u.openConnection();
uc.setDoOutput(true);
uc.setDoInput(true);
uc.setAllowUserInteraction(false);
DataOutputStream dos = new DataOutputStream(uc.getOutputStream());
// Send the data
dos.writeBytes(query);
dos.close();
// Read the response
DataInputStream dis = new DataInputStream(uc.getInputStream());
String nextline;
while((nextline = dis.readLine()) != null) {
System.out.println(nextline);
}
dis.close();
}
catch (Exception e) {
System.err.println(e);
}
如您所见,发布表单比使用GET方法复杂得多。但是,在某些平台上,一旦查询字符串增长到超过200个字符,GET就有一个烦人的习惯。GET失败的确切点取决于操作系统和Web服务器。