友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
Java编程思想第4版[中文版](PDF格式)-第132部分
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!
好这个表单,然后按下提交按钮,即可在浏览器的 URL 地址窗口里看到象下面这样的内容:
http://myhome。/cgi…bin/Listmgr2。exe?name=First+Last&email=email@domain。&submit=Submit
③:在Windows32 平台下,可利用与 Microsoft Office 97 或其他产品配套提供的 Microsoft Personal Web
Server (微软个人Web 服务器)进行测试。这是进行试验的最好方法,因为不必正式连入网络,可在本地环
境中完成测试(速度也非常快)。如果使用的是不同的平台,或者没有Office 97 或者FrontPage 98 那样的
产品,可到网上找一个免费的Web 服务器供自己测试。
当然,上述 URL 实际显示时是不会拆行的。从中可稍微看出如何对数据编码并传给CGI。至少有一件事情能
够肯定——空格是不允许的(因为它通常用于分隔命令行参数)。所有必需的空格都用“+”号替代,每个字
段都包含了字段名(具体由HTML 页决定),后面跟随一个“=”号以及正式的字段数据,最后用一个“&”结
束。
到这时,大家也许会对“+”,“=”以及“&”的使用产生疑惑。假如必须在字段里使用这些字符,那么该如
何声明呢?例如,我们可能使用“John & MarshaSmith ”这个名字,其中的“&”代表“And”。事实上,它
会编码成下面这个样子:
John+%26+Marsha+Smith
也就是说,特殊字符会转换成一个“%”,并在后面跟上它的十六进制ASCII 编码。
幸运的是,Java 有一个工具来帮助我们进行这种编码。这是URLEncoder 类的一个静态方法,名为
encode()。可用下述程序来试验这个方法:
//: EncodeDemo。java
// Demonstration of URLEncoder。encode()
import java。*;
public class EncodeDemo {
561
…………………………………………………………Page 563……………………………………………………………
public static void main(String'' args) {
String s = 〃〃;
for(int i = 0; i 《 args。length; i++)
s += args'i' + 〃 〃;
s = URLEncoder。encode(s。trim());
System。out。println(s);
}
} ///:~
该程序将获取一些命令行参数,把它们合并成一个由多个词构成的字串,各词之间用空格分隔(最后一个空
格用String。trim()剔除了)。随后对它们进行编码,并打印出来。
为调用一个 CGI 程序,程序片要做的全部事情就是从自己的字段或其他地方收集数据,将所有数据都编码成
正确的URL 样式,然后汇编到单独一个字串里。每个字段名后面都加上一个“=”符号,紧跟正式数据,再紧
跟一个“&”。为构建完整的 CGI 命令,我们将这个字串置于CGI 程序的 URL 以及一个“?”后。这是调用所
有CGI 程序的标准方法。大家马上就会看到,用一个程序片能够很轻松地完成所有这些编码与合并。
15。6。2 程序片
程序片实际要比NameSender。java 简单一些。这部分是由于很容易即可发出一个 GET 请求。此外,也不必等
候回复信息。现在有两个字段,而非一个,但大家会发现许多程序片都是熟悉的,请比较
NameSender。java 。
//: NameSender2。java
// An applet that sends an email address
// via a CGI GET; using Java 1。02。
import java。awt。*;
import java。applet。*;
import java。*;
import java。io。*;
public class NameSender2 extends Applet {
final String CGIProgram = 〃Listmgr2。exe〃;
Button send = new Button(
〃Add email address to mailing list〃);
TextField name = new TextField(
〃type your name here〃; 40);
email = new TextField(
〃type your email address here〃; 40);
String str = new String();
Label l = new Label(); l2 = new Label();
int vcount = 0;
public void init() {
setLayout(new BorderLayout());
Panel p = new Panel();
p。setLayout(new GridLayout(3; 1));
p。add(name);
p。add(email);
p。add(send);
add(〃North〃; p);
Panel labels = new Panel();
labels。setLayout(new GridLayout(2; 1));
labels。add(l);
labels。add(l2);
562
…………………………………………………………Page 564……………………………………………………………
add(〃Center〃; labels);
l。setText(〃Ready to send email address〃);
}
public boolean action (Event evt; Object arg) {
if(evt。target。equals(send)) {
l2。setText(〃〃);
// Check for errors in data:
if(name。getText()。trim()
。indexOf(' ') == …1) {
l。setText(
〃Please give first and last name〃);
l2。setText(〃〃);
return true;
}
str = email。getText()。trim();
if(str。indexOf(' ') != …1) {
l。setText(
〃Spaces not allowed in email name〃);
l2。setText(〃〃);
return true;
}
if(str。indexOf(';') != …1) {
l。setText(
〃mas not allowed in email name〃);
return true;
}
if(str。indexOf('@') == …1) {
l。setText(〃Email name must include '@'〃);
l2。setText(〃〃);
return true;
}
if(str。indexOf('@') == 0) {
l。setText (
〃Name must preceed '@' in email name〃);
l2。setText(〃〃);
return true;
}
String end =
str。substring(str。indexOf('@'));
if(end。indexOf('。') == …1) {
l。setText(〃Portion after '@' must 〃 +
〃have an extension; such as '。'〃);
l2。setText(〃〃);
return true;
}
// Build and encode the email data:
String emailData =
〃name=〃 + URLEncoder。encode(
name。getText()。trim()) +
〃&email=〃 + URLEncoder。encode(
email。getText()。trim()。toLowerCase()) +
〃&submit=Submit〃;
563
…………………………………………………………Page 565……………………………………………………………
// Send the name using CGI's GET process:
try {
l。setText(〃Sending。。。〃);
URL u = new URL(
getDocumentBase(); 〃cgi…bin/〃 +
CGIProgram + 〃?〃 + emailData);
l。setText(〃Sent: 〃 + email。getText());
send。setLabel(〃Re…send〃);
l2。setText(
〃Waiting for reply 〃 + ++vcount);
DataInputStream server =
new DataInputStream(u。openStream ());
String line;
while((line = server。readLine()) != null)
l2。setText(line);
} catch(MalformedURLException e) {
l。setText(〃Bad URl〃);
} catch(IOException e) {
l。setText(〃IO Exception〃);
}
}
else return super。action(evt; arg);
return true;
}
} ///:~
CGI 程序(不久即可看到)的名字是Listmgr2。exe。许多Web 服务器都在Unix 机器上运行(Linux 也越来越
受到青睐)。根据传统,它们一般不为自己的可执行程序采用。exe 扩展名。但在Unix 操作系统中,可以把
自己的程序称呼为自己希望的任何东西。若使用的是。exe 扩展名,程序毋需任何修改即可通过 Unix 和Win32
的运行测试。
和往常一样,程序片设置了自己的用户界面(这次是两个输入字段,不是一个)。唯一显著的区别是在
action()方法内产生的。该方法的作用是对按钮按下事件进行控制。名字检查过以后,大家会发现下述代码
行:
String emailData =
〃name=〃 + URLEncoder。encode(
name。getText()。trim()) +
〃&email=〃 + URLEncoder。encode(
email。getText()。trim()。toLowerCase()) +
〃&submit=Submit〃;
// Send the name using CGI's GET process:
try {
l。setText(〃Sending。。。〃);
URL u = new URL(
getDocumentBase(); 〃cgi…bin/〃 +
CGIProgram + 〃?〃 + emailData);
l。setText(〃Sent: 〃 + email。getText());
send。setLabel(〃Re…send〃);
l2。setText(
〃Waiting for reply 〃 + ++vcount);
DataInputStream server =
new DataInputStream(u。openStream());
564
…………………………………………………………Page 566……………………………………………………………
String line;
while((line = server。readLine()) != null)
l2。setText(line);
// 。。。
name 和 email 数据都是它们对应的文字框里提取出来,而且两端多余的空格都用trim()剔去了。为了进入列
表,email 名字被强制换成小写形式,以便能够准确地对比(防止基于大小写形式的错误判断)。来自每个
字段的数据都编码为URL 形式,随后采用与 HTML 页中一样的方式汇编GET 字串(这样一来,我们可将Java
程序片与现有的任何CGI 程序结合使用,以满足常规的 HTML GET 请求)。
到这时,一些Java 的魔力已经开始发挥作用了:如果想同任何URL 连接,只需创建一个URL 对象,并将地址
传递给构建器即可。构建器会负责建立同服务器的连接(对 Web 服务器来说,所有连接行动都是根据作为
URL 使用的字串来判断的)。就目前这种情况来说,URL 指向的是当前Web 站点的 cgi…bin 目录(当前Web 站
点的基础地址是用 getDocumentBase()设定的)。一旦Web 服务器在URL 中看到了一个“cgi…bin”,会接着
希望在它后面跟随了cgi…bin 目录内的某个程序的名字,那是我们要运行的目标程序。程序名后面是一个问
号以及CGI 程序会在QUERY_STRING 环境变量中查找的一个参数字串(马上就要学到)。
我们发出任何形式的请求后,一般都会得到一个回应的HTML 页。但若使用Java 的URL 对象,我们可以拦截
自CGI 程序传回的任何东西,只需从 URL 对象里取得一个 InputStream (输入数据流)即可。这是用URL 对
象的openStream()方法实现,它要封装到一个DataInputStream 里。随后就可以读取数据行,若readLine()
返回一个null (空值),就表明CGI 程序已结束了它的输出。
我们即将看到的CGI 程序返回的仅仅是一行,它是用于标志成功与否(以及失败的具体原因)的一个字串。
这一行会被捕获并置放第二个 Label 字段里,使用户看到具体发生了什么事情。
1。 从程序片里显示一个Web 页
程序亦可将 CGI 程序的结果作为一个Web 页显示出来,就象它们在普通 HTML 模式中运行那样。可用下述代码
做到这一点:
getAppletContext()。showDocument(u);
其中,u 代表URL 对象。这是将我们重新定向于另一个Web 页的一个简单例子。那个页凑巧是一个CGI 程序
的输出,但可以非常方便地进入一个原始的HTML 页,所以可以构建这个程序片,令其产生一个由密码保护的
网关,通过它进入自己Web 站点的特殊部分:
//: ShowHTML。java
import java。awt。*;
import java。applet。*;
import java。*;
import java。io。*;
public class ShowHTML extends Applet {
static final String CGIProgram = 〃MyCGIProgram〃;
Button send = new Button(〃Go〃);
Label l = new Label();
public void init() {
add(send);
add(l);
}
public boolean action (Event evt; Object arg) {
if(evt。target。equals(send)) {
try {
// This could be an HTML page instead of
// a CGI program。 Notice that this CGI
// program doesn't use arguments; but
// you can add them in the usual way。
URL u = new URL(
565
…………………………………………………………Page 567……………………………………………………………
getDocumentBase();
〃cgi…bin/〃 + CGIProgram);
// Display the output of the URL using
// the Web browser; as an ordinary page:
getAppletContext()。showDocument(u);
} catch(Exception e) {
l。setText(e。toString());
}
}
else return su
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!