使用Java语言编写CGI程序
公共网关界面(CGI)是一种编程标准,符合标准的程序(CGI程序),通过WEB服务器与运行WEB浏览器的客户进行交互。这些程序允许WEB开发者通过浏览器传送动态信息(通常嵌于HT
ML中)。CGI程序可用WEB浏览器能运行的任何语言来书写,其中包括Java。CGI程序通常用于加入搜索机制、客户登记应用程序、数据库查询机制、交互式用户论坛和其它一些WEB站点的交互式应用程序。
CGI程序必须解释发送给它的信息,并以某种方式处理这些信息,生成相应结果回送给客户。
CGI规定了一组标准的环境变量和参数格式,CGI程序的绝大多数输入通过环境变量传入程序内部。本文将演示如何把环境变量传递给一个Java程序。除环境变量之外的输入作为标准输入可直接被程序读取。
CGI程序的处理过程可能很简单,也可能象从一个数据库中请求数据那么复杂。这由具体处理需要而定。
CGI程序可以返回多种类型的文档。因此必须在输出内容中放置一个短的文档头(HEADE
R)(ASCII码文本),使客户知道该如何解释它生成的信息。CGI程序最常生成的是HTML文档。生成文档头之后,CGI程序以它的本机格式生成输出中的体(BODY)。在下文中我们将使用一个预先编制的Java库,它包含生成HTML文档头的方法header()。
一、将CGI环境变量传递给Java程序
编写CGI
Java程序较为容易。首先Java程序需要包在另一个脚本中运行。实际嵌入服务器的脚本将是能把环境变量传入Java程序的UNIX外壳脚本或Windows批处理文件。
由于Java不再提供直接访问环境变量的方法(最新的JDK版本取消system.getenv()方法),因此,建议使用Java解释器的-D命令行参数传递CGI的每个环境变量。下面将介绍如何使用D参数。
Java使用方法system.getproperty()来访问命令行参数。Java程序需要的任何一个CGI
环境变量,均可用上述方法来访问。例如,访问server-name环境变量,可写下行:
string server-name = system.getproperty("cgi.server-name");
下面是一个名为hello.cgi的UNIX脚本文件,它调用名为hello的Java程序。注意-D命令行参数把CGI环境变量传入Java程序:
#!/bin/sh
java \
-Dcgi.content-length=$CONTENT-LENGTH \
-Dcgi.request-method=$REQUEST-METHOD \
-Dcgi.query-string=$QUERY-STRING \
-Dcgi.server-name=$SERVER-NAME \
-Dcgi.server-port=$SERVER-PORT \
-Dcgi.script-name=$SCRIPT-NAME \
-Dcgi.path-info=$PATH-INFO \
hello
上述方案不能在Windows 95和Windows
NT平台上很好地实现,因为它们在命令行长度上有限制。但可以把环境变量名及其相关的值写入一个临时文件,然后将该文件名传递给Java
程序,Java程序读此文件并从中分析出环境变量/值对。
二、JAVA CGI库
为避免重复工作,简化编制程序的过程,可先将一些常用的或固定的处理写成函数或方法,组成函数库。以后编制CGI程序时,只需考虑主要的处理过程。下文中使用的方法Header()
和ReadParse假设已在名为cgi-lib.java的函数库中。
三、编制JAVA CGI程序
下面以编制第一节中被hello.cgi调用的hello.java程序为例,说明如何编制CGI程序。我们将编制一个简单程序来处理"Hello
There"格式。它提示用户NAME
和EMAIL地址。要处理的格式(名为hello.html)为:
Hello and Welcome!
Hello and Welcome
下面开始编制处理"Hello There"格式的Java
CGI程序,它实现与客户的交互。步骤如下:
1.首先,让客户知道该CGI程序将要生成HTML格式。在cgi-lib.java中方法Header()将生成所需的字符串,因此,Java程序将调用Header()方法及使用system.out.println系统调用打印字符串。
//
// 打印所需的CGI头
//
system.out.println( cgi-lib.Header( ) );
2.其次,要处理通过浏览器发送来的数据。在cgi-lib.java中ReadParse方法完成这方面的工作,并回送结果到一个哈希表中。本例中,经分析后哈希表的每项包括两个关键项值。一个是"name"输入域,另一个是"email"输入域。这两个域的值即是用户在"Hello
There"格式中输入的内容。
//
// 分析格式中数据后将其放入哈希表中(HashTable)
//
Hashtable form-data=cgi-lib.ReadParse(system.in)
3.在分析并获取格式数据后,就可以根据需要处理这些数据。完成所需的处
理后再生成HTML文档回送到用户浏览器。为简单起见,本例将不对这些数据作任何处理,仅仅把它们回送给发数据的用户。我们将对哈希表对象使用get方法,以选取格式数据值赋给字符串,供程序使用。下例说明如何选取name的值(由用户键入)给一个字符串对象。
string name=(str ing)form-data.get("name");
综合以上三步,可以生成一个简单程序,即下述用于处理"Hello
There"格式的Java应用程序(hello.java):
import java.util.*;
import java.io.*;
class hello
public static void main( string args[ ])
//
// Here is a minimalistic CGI program that uses cgi-li
b
//
//
// Print the required CGI header.
//
system.out.println( cgi-lib.Header( ) );
//
// Parse the form data into a Hashtable.
//
Hashtable form-data=cgi-lib.ReadParse(system.in);
//
// Create the top of the returned HTML page
//
string name=(string)form-data.get("name");
system.out.println(cgi-lib.Htmltop("Hello There"+name+
"!"));
system.out.println("Hello There"+name
+ "!
");
system.out.println("Here are the name/value pairs from
the form:");
//
// Print the name/value pairs sent from browser.
//
system.out.println(cgi-lib.Variables(form-data));
//
// Print the Environment variables sent in form the un
ix script.
//
system.out.println("Here are the CGIenvironment variab
les/value pairs"+
"Passed in form the UNIX script:");
system.out.println( cgi-lib.Environment( ) );
//
// Create the Bottom of rturned HTML page to close it
cleanly.
//
system.out.println( cgi-lib.HtmlBot( ) );
四、结论
在初步掌握了用Java编写CGI程序的方法之后,我们可以在自己的Web应用中,以更为适合的方式开发服务器端的应用程序。同时加深对CGI协议的理解,正是CGI协议为客户浏览器和服务器提供了这种通迅途径,使客户可以和Web服务器进行交互。
Java与C/C++
内容提要|C、C++及Java的演变
Java 和C/C++的对比|参考文献
内容提要
Java语言是一种新型的面向对象的语言。它比C 或C++ 都易于学
习和开发。它与C 或C++ 并非完全不同,但是,在Java 中见不到C
及C++ 中复杂易出错的结构,取而代之的是高可移植性和高安全性的
特点使Java 应用程序(包括小应用程序)在不同的网络环境中都能
运行。Java 的主要问题在于它的某些特性(例如字节码的检验及翻?
搿⑹楸咴导煅椤⒅С侄嘞叱探峁埂⒛诖娴ピ厥占捌教ㄎ薰匦裕┯
跋熘葱械目ava 的中立性需要在不同的平台上测试,同时它那
被大大夸张的可移植性是以性能损失为代价的。
C、C++及Java的演变
自从1972 年,贝尔实验室的Dennis Ritchie 发明了C 语言之
后, 它在全世界广为流行(1 )。它的成功是由于那些有用途的特
性(例如数据类型代表计算机硬件的能力,规模较小及简单易学)。
标准运行时库(用于输入/ 输出 、存贮分配及字符串操作的功能)
以及一大套开发工具(UNIX 操作系统在这方面做出很大贡献,其它
的操作系统也紧随其后)。
时过境迁,计算机应用程序日益复杂,维护及扩展现存的C 语言
应用程序成了一件大事(2),这一切促成了C++ 语言的早期版本
(普遍被称为“有类的C 语言”),该版本在1980 年后被启用,
1983 年,现在使用的C++ 产生,到了1987 年,C++开始被标准化。
C++ 语言是专为增加大型程序的可读性和易维护性而设计的。C 语言
被选择作为C++ 的蓝本是由于这是一种较低级的语言并适合系统编
程,另一个原因是已存的C 语言有大量应用程序和书籍,标准化机构
规定C++ 语言必须兼容C 语言,并且竭尽全力确保C 和C++ 之间的合
法结构,避免重写任何C 程序,手册及工具。这一切使得C语言程序
员能够轻松地转向C++ 。 被迫与C 语言的兼容使C++ 的问题重重。
最主要的有:指针运算、数组索引、出边缘值的检验、各种各样的函
数参数以及未检验的类型转换。
Java 语言的发展始于1991年早期的Sun Microsystems。开始
时,这是一个为网络设备及用户电器设备开发软件的研究计划(3
)。在这个过程中(最后被称为“绿”计划 ),James Gosling 及
其他的项目工程师们对于可靠性,费用,标准和简易性有了更多的认
识。 到了1994 年中,Sun 公司的WWW 爆发了。“我们意识到我们能
做出很棒的浏览器”Gosling 说,“这是我们在客户/ 服务器主流中
所要完成 的几件奇怪的事情之一:中性结构、实时性、可靠性、安
全性--那些在工作站系统中不是那么重要的事。”那种语言即发展
为今天的Java 。
Java 和C/C++的对比
Java 和C/C++ 有许多不同之处,我将按照主要特性一一对比:
开发环境、性能、可移植性(希望读者略懂Java 语言(4 ))。
1 、语言特性
类型定义(Typedef) 、定义(define) 解释和预处理:
(preprocessor) :这一切在Java 中都不存在,以显得更简单,这
些结构的删除使Java 对上下文的依赖更小,程序员能够更简单地阅
读和理解代码,并修改和重新使用代码(5 )。
指针类型和算术运算:Java 语言并不直接使用指针,对象通过
参数被实现,即使参数实际上起到了指针的作用。Java 语言并不支
持指针运算。 这个特性减少了运行失误,在其它语言中,非法存取
会导致程序或系统的崩溃,这是 C/C++ 和Java 的巨大差别之一。这
个特性有以下的益处:Java 程序能在“sand box”中被运行,更简
单的代码的检验,更高的安全性。
枚举(Enumeration ) 类型:Java 语言不支持枚举
Enumeration ) 类型 ,而在C++ 中极为严格(比如:除非你使用显
式的类型,C++ 编译器不会允许你把不同枚举( Enumeration ) 类型
相互转换。 你也不能对某种枚举(Enumeration) 类型赋值)。
结构、联合( Union ) 和函数:为了简便,Java 语言删去了结
构和联合 。结构和联合能通过使用类来实现(联合还可使用超类
)。C 和C++ 能提供的函数,通过正确使用类功能在Java中都能实
现。
GOTO 语句:Java 语言取消了该语句以使程序更易读和易维护。
多重继承:C++ 支持多重继承,而Java 只能有一个超类,不过
用户可通过界面实现多重继承,并提供界面中没有的变量。
重载操作:在Java 语言中,程序员不能使标准算术符号重载,
但是,通过声明一组适当的实例变量和方法并对这些变量进行操作,
程序员能够实现重载操作。
浮点运算:Java 对浮点运算的要求似乎是对每个浮点运算都对
浮点结果按精度取整。对于为中间浮点结果而使用高精度的结构,
Java要求运算器返回上一级菜单相对自身能力所及低一些的中间结
果。过多的精度位数必须按Java 定义削减,这不仅导致了浮点运算
精度的降低,也使Java 程序的执行开销有重大影响 。这种情况
C/C++ 中不存在(如想知道关于这个问题的详细信息,请参考Roger
Gollire的论文“First ImplementationArtifacts in Java ”)。
数组边缘检验:在Java 中,负的数组大小或界限外索引会导致
运行出错,而在 C/C++ 中,无该项错误检验功能。
字符串:Java 字符串是字符串类构成的事件,不象C 字符串 ,
Java 字符串是不可变的。字符串缓冲区(可变字符串对象)的类是
Java 中可修改的字符串对象。
类型体系:Java 语言定义了合法类型体系,正如C/C++ 支持C
风格体系 这会导致类型冲突。
多线程:Java 语言支持多线 程结构,而C/C++ 语言无此特性。
另一方面,根据实现情况,对有些单线程Java 应用程序可能有性能
开销。
内存单元回收:Java 语言支持内存单元回收,然而,程序不能
管理动态分配的堆栈空间。但Java 的内存管理能跟踪对象参数。当
一 个对象没有引用时,即成为被内存单元回收的候选者。程序也能
启动内存单元回收动作。这一装置在C / C++ 中不存在。这一特性使
得Java程序更易编写,然而,这功能无法关闭(Java有" noasyncgc
" 选项关闭不同步GC )对于需要实时响应的应用程序,内存单元回
收的开销可能成为问题。
网络:Java 语言支持网络动作,并隐藏接口界面,使客户/ 服
务器应用程序更容易开发。C 及C++ 并不提供此项功能。
2 、开发/运行环境
Java 在过去两年中获得大量推动。国际数据公司(IDC )估计
在1997 年,将有大约300,000 份Java 快速应用程序开发软件(RAD
)集成开发环境(IDE)工具的发货量。那是个令人印象深刻的数
字。但与IDC 作出的,在年底前将有一百二十八万开发商为C++ 许可
而付费的估计相比仍然相形见拙。极少有C++ 开发商改换门庭。IDC
预计90%以上现存拥 C++ 许可证的开发商将升级至其所选工具的下
一版本。 俄勒冈州波特兰的Market Decisions 公司对750 位开发商
进行调查。24% 说在过去六个月中C++ 是他们项目开发使用得最多的
工具,比五个月前类似调查结果的26%低。6%报告说Java为他们主
要工具,是五个月前的两倍(6 )。 由于Java 语言相对较新,可以
理解开发所需工具尚未成熟。“我们认为决定Java 渗透性的一个最
好的指标是基于观察Java RAD 工具的增加。”Evan Quinn ,IDC 分
析员说。他总结:“Java RAD 真正成熟 时,它会向客户机/ 服务器
发出挑战。”(6 ) 由于Java 执行环境与C 及C++ 不尽相同,性能
始终是重要的事。Java 应用程序是解释程序而非?C/C++ 程序那样是
经过编译后与本地代码连接。 Java 应用程序首先被编译为字节代
码,然后在本地或通过网络在远程虚拟机上解释。Java 字节代码规
模较小,然而每次调用时相同代码都会被解释。因此其性能较同类产
品为慢。(即如果代码用Java 编写), 即时(JIT )编译器将字节
代码翻译为本地码而执行。它提高了性能,因为翻译只做一次,而不
是每次被调用时都做。JIT 虽提高了Java 的性能,但在本地码执行
速度上尚有不足。希望本地Java 编译器能解决这一问题。
3 、可移植性
C/C++ 程序被移植到其它机器上时一般会遇到问题。例如:这些
语言没有分配初始数据类型的标准。在转换初始类型时,C及C++ 不
指定正确结果。Java 语言为有Java 虚拟机的计算机上运行的应用程
序而设计。Java 的口号“编写一次,任意运行”即其指导性的目
标。 然而,由于Java 运行时在不同的主机上完成,它有主机特定的
模块 。我们怎么能不先试验而保证一个Java 应用程序在不同的平台
上总会有相同的性能呢?例如,根据主机操作系统不同线程调度。
一个多线程的Java 应用程序可能在不同计算机环境下有不同性能。
一个“100%纯Java ”(100% Pure Java)应用程序应该在不同平
台上测试以保证其质量。 Java 程序比C 及C++ 有更强的可移植性。
但为了质量原因仍建议 Java 程序,以及 C 和C++ 程序,在不同平
台上进行测试。如今市场上有各种各样的虚拟机(VM),但不清楚VM
测试组件有多全面。
4 、性能
C++ 被认为比Java 更成熟。在对众多Java 软件开发商的采访
中,CNET 的NEWS.COM 发现许多软件商在他们的Java 应用程序中使
用了一定量的本地码(Native Cade)。这些公司包括IBM,
Netscape, Microsoft, DimesionX,RandomNoise 及Net Dynamics(
7)。 由于各种理由,许多发展商发现要完全用Java 代码编写应用
程序虽非不可能,却也相当困难。一种普遍的理由是性能与C 版本相
比,经解释的Java 代码较慢。(1996 年8 月报告慢10倍(8),
1997 年5 月报告慢10 到20 倍(9))。JIT 编译器改善了这一状
况。(速度增加10 到25 倍(8),1997 年6 月报告速度增加1 到4
倍(10))。Java 本地编译器希望能提供三者中最佳性能
(Asymetrix宣布速度增加50倍(8 ),4到7 倍(10 ))。
一般来说,Java 语言不提供用于人工最优设置的标准钩子
(hook) (如C/C++的注册关键字(register keyword) 或 asm )。
Java 不支持内嵌本地汇编代码以帮助编译器代码形成。在Java 设计
中,简易性和可移植性是比性能更重要的因素。Java 更依靠编译器
和运行时提供性能。根据Market Decision 公司(位于波特兰的一家
独立研究公司),96% 的Java 发展商正在开发、配置Windows 中的
Java 应用软件--是Java 发展商配置在任何其它平台上的应用程序
的两倍多(12)。而大部分Java 应用程序在英特尔架构的平台上运
行。 Java 的浮点语法要求这样一种结构,它能提供更高的中间操作
的解决方法,而放弃精确性。这一要求不仅导致Java 程序较低的精
确性,而且也损害了应用程序的性能。仅就这一点上,Java 并未完
全使用处理器的能力。由于Java 宣布应用程序会因为低准确性而在
运行时间上付出代价,它不太可能用作浮点运算深层次应用程序的主
要语言。 如果考虑到在Java 语言语法中,每次方法调用都需查找方
法列表,Java 的运行时调用通常比C 的高而与C++ 相仿。Java 的错
误查找比C 及C++ 要求更长的运行时。有理由得出这样的结论:有了
一个好的本地Java 编译器,Java 性能能与C++ 性能相仿。
结论
与C++ 一样,Java 是面向对象的语言但更简单。对C 和C++ 程
序员来说,Java 应该并不陌生,因为Java ,C 和C++ 有相似的语言
结构。在 C++ 语言上去除了一些复杂功能并加入错误检查,内存单
元回收和多线程的支持后,Java 程序应该会相对来说更强壮。具有
内置的安全特性,Java 应用程序可用Java 虚拟机在多种网络环境中
解释。目前,Java 开发环境成熟性不能与本地C/C++ 相比,Java 代
码解释速度较慢。JIT 编译器和Java 本地编译器虽然正在不断改
进,但尚不能证明其与C/ C++ 已经成为竞争对手。 Java 开发商必
须在对Java 的期望中现实一些(13 )。Java 所提供的不 是传统意
义上的语言,也是一种完整的环境--虚拟机和网络环境(包括
Internet )。要被作为一种主流语言采用,Java 必须有完整的功
能,简单易用并可靠,而且运行成本低。这一随处可见的新语言仍需
作许多改进。
参考文献
(1) C-A Reference Manual by Samuel P. Harbison and Guy
L. Steele
Jr., Tartan Laboratories.
(2) The C++ program Language by Bjarne Stroubtrup,
AT&T Bell Laboratories.
(3) Java: The inside story, Michael O'Connell, Sun World
Online.
(4) The Java Language Specification, James Gosling, Bill
Joy and Guy Steele, Addison-Wesley.
(5) The Java Language Environment, A White Paper, James
Gosling, Henry McGilton,
Sun Microsystems Computer Company.
(6) Java hype aside, C++ still rules, Mike Ricciuti,
C/Net,
http://www.news.com/News/Item/0,4,10705,00.htm
(May 15,1997)
(7) 100% Pure Java watered
down,http://www.news.com/News/Item/0,4,11069,00.htm
(8) Java-What's All The Excitement About?, Mark Volkmann,
Object Computing, Inc.(OCI).
http://www.cs.umsl.edu/-feldt/sluugls/meeting_notes/
1996/aug/java.htm
(9) JCC-A Java to C converter, Nik Shavlor, May 8,1997,
http://www.digiserve.com/nshaylor/jcc.htm
(10) IBM High Performance CompilerTM for Java(TM):
An Optimizing Native
Code Compiler for Java Applications, white paper,
following "High
Performance Compiler for Java" link from
http://www3.alphaworks.ibm.com/Home
(11) Experiences Converting a C++ Communication Software
Framework to Java, Prashant Jain and Douglas
C. Schmidt
Jan 1997,C++Report,
http://siesta.cs.wustl.edu/-pjain/java/java_notes.htm
(12)MS dev tools exceed expectations,
http://www.javaworld.com/javaworld/jw-06-1997/
jw-06-newsbriefs.
html#MSDEV
(13) Overpromised and underperforming, Java collides with
reality, T.C
Doyle,
http://techweb.cmp.com/vb/june/169cover.htm
JAVA语言学习
作者:顾振宇和刘啸林
您可以自由下载本文,但请保留作者信息。
本文选自上海交大即将出版的『实用JAVA教程』。
第4章 Java对多媒体的支持
4.1 图形与文本
4.1.1 图形的绘制
4.1.2 文本与字体
4.1.3 颜色的设置
4.2 图像与声音
4.2.1 图像文件的显示
4.2.2 声音文件的播放
4.3 动画制作
4.3.1 一个简单实例
4.3.2 引入线程机制
4.3.3 初识闪烁问题
4.3.4 放映图像
4.3.5 使用媒体跟踪器
4.3.6 移动型动画
4.3.7 双缓冲技术
练习题
第五章 输入、界面和网络
5.1 接收鼠标、键盘的输入
5.1.1 鼠标的按键
5.1.2 鼠标的移动
5.1.3 键盘的输入
5.1.4 事件处理器(Event Handler)
5.2 用户界面设计
5.2.1 抽象窗口工具箱(AWT)概述
5.2.2 UI基本元素
5.2.3 版面设置
5.2.4 事件的处理
5.2.5 窗口构造构件
5.3 网络编程
5.3.1 网络资源的使用
5.3.2 Socket编程
5.3.3 数据报
练习题