Java CGI HOWTO 中译版 <author> 作者: David H. Silber <tt><htmlurl url="mailto:javacgi-document@orbits.com" name="javacgi-document@orbits.com"></tt><newline> 译者: <htmlurl url="http://www.phys.ntu.edu.tw/~cwhuang/pub/" name="黄志伟"> <tt><htmlurl url="mailto:cwhuang@phys.ntu.edu.tw" name="cwhuang@phys.ntu.edu.tw"></tt> <date>v0.5, 1 December 1998 翻译日期: 17 December 1998 <!-- v0.4, 21-25 August 1997 --> <abstract> 本文解释如何设定你的伺服器,使其能使用 Java 来写 CGI 程式,以及如何用 Java 来写 CGI 程式. 虽然 HOWTO 文件的目的是用在 Linux 作业系统上,但这篇特别的文章事实上与特定版本的 UNIX 系统无关. </abstract> <toc> <sect>简介 <p> 由於 Java 的设计方式程式设计师没有简易的方法可以取得系统的环境变数. 由於 Java 发展工具 (JDK) 建立的方式,呼叫一个程式必须使用多重表徵(tokens), 这和标准的 HTML forms/CGI 运作方式不易配合. 有一些办法可以克服这些限制,而我就实作了其中一种.详情请见下述. 我写下前段的时间是 1996. 到现在 Java 的技术已经有很大的改变了。 目前可能有更好的方法来执行伺服器端的 Java 程式 -- 也许你应该看一看 servlets(?). <sect1>预备知识 <p> 我假定你有 HTML 与 CGI 概念的一般知识,而且了解关於你的 HTTP 伺服器的最基本知识. 你也应该知道如何写 Java 程式,否则这些都没有意义. <sect1>这份文件 <p> 本文的最新版本可以从此找到: <htmlurl url="http://www.orbits.com/software/Java_CGI.html" name="http://www.orbits.com/software/Java_CGI.html">. <sect1>软体套件 <p> 本文所提到的软体套件的最新版本可由匿名 FTP 取得 <htmlurl url="ftp://ftp.orbits.com/pub/software/java_cgi-0.5.tgz" name="ftp://ftp.orbits.com/pub/software/java_cgi-0.5.tgz">. 这套件包含本文的 SGML 原始档. <p> 这些套件的散布必须依据 GNU Library General Public License. 本文可依 Linux HOWTO 的版权声明散布. <p> 如果你使用本软体,请制作一些参考指向 <htmlurl url="http://www.orbits.com/software/Java_CGI.html" name="http://www.orbits.com/software/Java_CGI.html">, 以便让其它人能找到 Java CGI 的类别. 我已经没有时间再去维护这个套件,因此这或许是最後一版了。 如果有人非常地喜欢这个程式,而想接手维护,请与我联络: <tt><htmlurl url="mailto:javacgi-document@orbits.com" name="javacgi-document@orbits.com"></tt> <sect1>The Mailing List <label id="mailing-list"> <p> 我已经建了一个 majordomo 通信论坛让使用本程式的人们可以互相帮忙解决问题。 请送信件到 <tt><htmlurl url="mailto:javacgi-request@orbits.com" name="javacgi-request@orbits.com"></tt> 内容包含 <em>subscribe</em> 这个字。 <sect>设定伺服器以执行 Java CGI 程式 (解释篇) <label id="install-long"> <p> 这一节教你安装我的 <em>Java CGI</em> 套件,以及大量的解释,让你能够了解你的行为会导致什麽结果. 如果你只想安装程式而不想了解为什麽,直接跳到 <ref id="install-short" name="设定伺服器以执行 Java CGI 程式 (简略篇)">. <sect1>系统需求 <p> 本软体应该能在已安装 Java 程式发展工具的任何类 UNIX 的 web 伺服器上安装. 我将它装在执行 <em>apache</em> 伺服器的 <em>Debian Linux</em> 系统上. 如果你发觉它无法在你的伺服器上运作,请利用通信论坛. 细节请见 <ref id="mailing-list" name="The Mailing List">. <p> 不幸的是,Java 执行时期解译器似乎是吃记忆体的怪物 -- 如果你将使用许多 Java CGI 程式的话你可能要再丢数 MB 的 RAM 到你的伺服器里. <sect1>Java CGI 辅助软体 <p> 我写的辅助软体就叫做 <em>Java CGI</em>.你可从 <htmlurl url="ftp://ftp.orbits.com/pub/software/java_cgi-0.5.tgz" name="ftp://ftp.orbits.com/pub/software/java_cgi-0.5.tgz"> 取得(版本号码可能会改变). <sect1>解开原始档 <p> 找一个合适的目录将套件解开. (如果你还没有标准放置软体的地方,我建议你放在 <tt>/usr/local/src</tt>.) 用这个指令解开套件: <verb> gzip -dc java_cgi-0.5.tgz | tar -xvf - </verb> 这会产生一个叫 <tt>java_cgi-0.5</tt> 的目录. 在那里你可以找到本文其它地方提到的档案. (如果版本号码改变了,就改用那套件里的.) <sect1>决定你的本地目录策略 <label id="make-programs"> <p> 你必须决定让你的 Java CGI 程式住在那里. 一般来说,你会希望放在和你的 <tt>cgi-bin</tt> 平行的目录. 我的 <em>apache</em> 伺服器设定使用 <tt>/var/www/cgi-bin</tt> 为 <tt>cgi-bin</tt> 目录, 因此我用 <tt>/var/www/javacgi</tt> 作为放置 Java CGI 程式的地方. 你可能不会想让将你的 Java CGI 程式放进某一已存在的 <tt>CLASSPATH</tt> 目录. 编辑 Makefile 来反应你的系统配置.确定你用 root 签入然後执行 <tt>make install</tt>. 这将编译 Java 程式,修改 <tt>java.cgi</tt> 指令稿以符合你的系统,并且将程式安装进适当的位置. 如果你希望拥有本文的 HTML 版本以及一份 HTML 测试文件,改用 <tt>make all</tt>. <sect1>测试你的安装 <label id="install-test"> <p> 由本套件安装的 HTML 文件叫做 <tt>javacgitest.html</tt>, <tt>javaemailtest.html</tt> 以及 <tt>javahtmltest.html</tt>. 如果你在前节使用 <tt>make all</tt>,它们会放在你於 Makefile 中指定的 <tt/WEBDIR/ 目录中. 如果不是,你可以执行 <tt>make test</tt> 从 <tt>javacgitest.html-dist</tt>, <tt>javaemailtest.html-dist</tt> 以及 <tt>javahtmltest.html-dist</tt> 来建立它们. <p> 当你确定你的安装可以正确运作後,你可能希望从你的 JAVACGI 目录移除 <tt>CGI_Test</tt>, <tt>Email_Test</tt> 以及 <tt>HTML_Test</tt> 类别,还有从 <tt/WEBDIR/ 目录移除 <tt>javacgitest.html</tt>, <tt>javaemailtest.html</tt> 以及<tt>javahtmltest.html</tt>,因为它们会显示应该只有伺服器管理者才看得到的使用者资讯. <sect>设定伺服器以执行 Java CGI 程式 (简略篇) <label id="install-short"> <p> <enum> <item> 从 <htmlurl url="ftp://ftp.orbits.com/pub/software/java_cgi-0.5.tgz" name="ftp://ftp.orbits.com/pub/software/java_cgi-0.5.tgz">. 取回 <em>Java CGI</em> 套件.(版本号码可能会改变.) </item> <item> 用这个指令解开套件: <verb> gzip -dc java_cgi-0.5.tgz | tar -xvf - </verb> (如果版本号码改变了,就改用那套件里的.) </item> <item> 修改在新产生的 <tt>java_cgi-0.5</tt> 目录里的 <tt>Makefile</tt> 以符合你的系统. </item> <item> 以 root 身份,执行 <tt>make install</tt>. 这将编译 Java 程式,加上你系统特定的资讯并安装许多档案. 如果你希望拥有本文的 HTML 版本以及一份 HTML 测试文件,改用 <tt>make all</tt>. </item> <item> 然後应该就可以用了. </item> </enum> <sect>执行一个 Java CGI 程式 <p> <sect1>以 CGI 模式执行 Java 程式的障碍 <p> 从 web 伺服器执行 Java 程式有两个主要的问题: <sect2>你不能像一般执行档一样执行 Java 程式 <p> 你必需执行 Java 的执行时刻(run-time)解译器并且以命令列的方式提供初始类别(程式执行所需). 在一个 HTML form 里面没有办法提供命令列给 web 伺服器. <sect2>Java 程式没有一般的方法可以取得环境变数 <p> Java 程式所需的每个环境变数都必需被传入. (在 Java 程式中)没有类似 <bf>C</bf> 语言的 <tt>getenv()</tt> 函数. <sect1>执行 Java CGI 解决问题 <p> 为了处理这些困难,我写了一个 CGI 指令稿程式,提供 Java 解译器所需的资讯. <sect2>java.cgi 指令稿 <p> 这个指令稿管理 HTTP 伺服器与你希望使用的 Java CGI 程式之间的互动. 它从 server 端提供的资料中取出你想要执行程式的名称. 它将所有的环境变数资料将髹到一个暂存档里.然後,它将这个档案以及程式名称加命令列中, 执行 Java 的执行时刻解译器. <tt>java.cgi</tt> 指令稿的设定与安装在 <ref id="make-programs" name="决定你的本地目录策略"> 一节说明. <sect2>从 HTML form 中引发 java.cgi <p> 使用 Java CGI 程式的 HTML form 以下面的方式指定其行为: <verb> <form action="/cgi-bin/java.cgi/CGI_Test" method="POST"> </verb> 其中 <tt>/cgi-bin/</tt> 是你本地端的 CGI 二进位执行档目录, <tt>java.cgi</tt> 是允许我们从 web 上执行 Java 程式的前端, 而 <tt>CGI_Test</tt> 是一个欲执行的 Java 程式名称的例子. <sect>使用 Java CGI 类别 <p> 目前为止支援三个主要类别 -- <ref id="cgi-class" name=CGI>, <ref id="email-class" name=Email> 以及 <ref id="html-class" name=HTML>. 我正在考虑分别加上处理 MIME 格式输入与输出的类别 -- MIMEin & MIMEout. <p> 也有一些用来支援和测试的类别. <ref id="cgi-test-class" name="CGI_Test">, <ref id="email-test-class" name="Email_Test"> 以及 <ref id="email-test-class" name="HTML_Test"> 是拿来测试你的安装用的. 你也可拿来当做你自己程式中使用这些类别库的起点. <ref id="text-class" name=Text> 类别是 <tt>Email</tt> 与 <tt>HTML</tt> 的基底类别. <sect1>CGI<label id="cgi-class"> <p> <sect2>类别语法 <p> <tt>public class CGI</tt> <sect2>类别描述 <p> CGI 类别持有的「CGI 资讯」 -- web 伺服器所设定的环境变数以及按下 <bf>submit</bf> 时由 form 所传送来的名称/数值. 所有的资讯都被存放在类别物件 <tt>Properties</tt> 中. <p> 这个类别位於 ``Orbits.net'' 包装(package)中. <sect2>成员摘要 <p> <code> CGI() // 建构子 getNames() // 取得名称的串列 getValue() // 取得指定名称的值 </code> <sect2>请参阅 <p> <tt>CGI_Test</tt>. <sect2>CGI() <p> <descrip> <tag/目的/ 建构一包含可用 CGI 资料的物件 <tag/语法/ <tt>public CGI()</tt> <tag/描述/ 当一 CGI 物件被建立时,所有可用的 CGI 资料被存放在新物件的局部储存空间中. </descrip> <sect2>getNames() <p> <descrip> <tag/目的/ 列出已定义对应值的名称. <tag/语法/ <tt>public Enumeration getNames ()</tt> <tag/描述/ 提供所有已定义对应值的名称的完整列表. <tag/返回 / 所有名称的 <tt>Enumeration</tt> 物件. </descrip> <sect2>getValue() <p> <descrip> <tag/目的/ 取回所指定对应於 <bf>name</bf> 的 <bf>value</bf>. <tag/语法/ <tt>public String getValue ( String name )</tt> <tag/描述/ 这个方法提供由 HTML form 送入的 <tt>names</tt> 与 <tt>values</tt> 之间的对应. <tag>参数 <descrip> <tag/name/ 所选择的键值. </descrip> <tag/返回 / 一个包含对应值的 <tt>String</tt> 物件. </descrip> <sect1>CGI_Test<label id="cgi-test-class"> <p> 这个类别提供两个功能,一个如何使用 <tt>CGI</tt> 类别的例子以及一个用来确定 <em>Java CGI</em> 套件运作正常的测试程式. <sect2>成员摘要 <p> <code> main() // Program main(). </code> <sect2>请参阅 <p> <tt><ref id="cgi-class" name=CGI></tt>. <sect2>main() <p> <descrip> <tag/目的/ 提供 <tt>main()</tt> 方法. <tag/语法/ <tt>public static void main( String argv[] )</tt> <tag/描述/ 这是 CGI 程式的入口,只不过返回可用的名称/数值对与其现值的列表. <tag>参数 <descrip> <tag/argv[]/ 由 <tt>java.cgi</tt> 指令稿传入的参数.目前未使用. </descrip> </descrip> <sect1>Email<label id="email-class"> <p> <sect2>类别语法 <p> <tt>public class Email extends Text</tt> <sect2>类别描述 <p> 讯息由 <tt>Text</tt> 类别的 <tt>add*()</tt> 方法所建立,加入电子邮件专用的方法. 完成後,讯息被送到它的目的地. <p> 这个类别位於 ``Orbits.net'' 包装中. <sect2>成员摘要 <p> <code> Email() // 建构子 send() // 送出电子邮件讯息 sendTo() // 增加讯息的目的地 subject() // 设定讯息的主题 </code> <sect2>请参阅 <p> <tt>Email_Test, Text</tt>. <sect2>Email() <p> <descrip> <tag/目的/ 建立一包含电子邮件讯息的物件. <tag/语法/ <tt>public Email()</tt> <tag/描述/ 建立一空的讯息以利由此类别方法加以完成. <tag/请参阅/ <tt>Text</tt>. </descrip> <sect2>send() <p> <descrip> <tag/目的/ 送出电子邮件讯息. <tag/语法/ <tt>public void send ()</tt> <tag/描述/ 本方法编排并送出讯息.如果目的位址还未设定,将不会有动作发生. </descrip> <sect2>sendTo() <p> <descrip> <tag/目的/ 增加本讯息的目的地. <tag/语法/ <tt>public String sendTo ( String address )</tt> <tag/描述/ 将 <tt>address</tt> 加入到目的地列表中.一份电子邮件目的地的数目是没有限制的. 不过我相信如果你建了过大的列表,你将可能会超过你的<em/邮件传送代理程式(MTA)/ 所能接受的大小或用光你的记忆体. <tag/参数/ <descrip> <tag/address/ 本讯息欲送达的一个目的地. </descrip> </descrip> <sect2>subject() <p> <descrip> <tag/目的/ 设定本讯息的主题. <tag/语法/ <tt>public void subject ( String subject )</tt> <tag/描述/ 本方法设定电子邮件的 <tt>Subject:</tt> 栏位. 如果呼叫超过一次以上,会使用最後一次呼叫的结果. <tag/参数/ <descrip> <tag/subject/ <tt>Subject:</tt> 栏位的文字. </descrip> </descrip> <sect1>Email_Test<label id="email-test-class"> <p> 这个类别提供一个如何使用 <tt>Email</tt> 类别的例子以及一个用来确定 <em>Java CGI</em> 套件运作正常的测试程式. <sect2>成员摘要 <p> <code> main() // Program main(). </code> <sect2>请参阅 <p> <tt><ref id="email-class" name=Email></tt>. <sect2>main() <p> <descrip> <tag/目的/ 提供 <tt>main()</tt> 方法. <tag/语法/ <tt>public static void main( String argv[] )</tt> <tag/描述/ 这是 CGI 程式的入口,返回可用的名称/数值对与其现值的列表. 它也将列表送到由 <tt>Email</tt> 变数所指定的位址. <tag>参数 <descrip> <tag/argv[]/ 由 <tt>java.cgi</tt> 指令稿传入的参数.目前未使用. </descrip> </descrip> <sect1>HTML<label id="html-class"> <p> <sect2>类别语法 <p> <tt>public class HTML extends Text</tt> <sect2>类别描述 <p> 讯息由 <tt>Text</tt> 类别的 <tt>add*()</tt> 方法所建立,并加入 HTML 专用的方法. 完成後,讯息被送到它的目的地. <p> 目前,还没有错误检查机制以确保列表建立的方法被以正确的顺序使用. 因此程式设计者必须自行确定没有违反 HTML 的语法. <p> 这个类别位於 ``Orbits.net'' 包装中. <sect2>成员摘要 <p> <code> HTML() // 建构子 author() // 设定文件作者的名字 definitionList() // 起始一定义列表 definitionListTerm() // 在定义列表中增加一项目 endList() // 结束列表 listItem() // 在列表中增加一项目 send() // 送出此 HTML 讯息 title() // 设定文件标题的文字 </code> <sect2>请参阅 <p> <tt>HTML_Test, Text</tt>. <sect2>HTML() <p> <descrip> <tag/目的/ 建立一包含 HTML 讯息的物件. <tag/语法/ <tt>public HTML()</tt> <tag/描述/ 建立一空的讯息以利由 HTML 方法加以完成. <tag/请参阅/ <tt>Text</tt>. </descrip> <sect2>author() <p> <descrip> <tag/目的/ 设定文件作者的名字. <tag/语法/ <tt>public void author ( String author )</tt> <tag/描述/ 将文件的作者名字设定为 <tt>author</tt>. <tag/参数/ <descrip> <tag/author/ 用来作为此讯息作者的文字. </descrip> <tag/请参阅/ <tt>title()</tt>. </descrip> <sect2>definitionList() <p> <descrip> <tag/目的/ 起始一定义列表. <tag/语法/ <tt>public void definitionList ()</tt> <tag/描述/ 起始一定义列表. 一个<em>定义列表</em>是一种特别的列表,列表中的每一项是由 <em>项目</em> 其後跟著定义的 <em>文字</em> 所形成的. 一定义列表的起始应跟著(至少)一项目/文字配对以及一个 <tt>endList()</tt> 方法的呼叫. <em>请注意,目前列表不能是巢状的</em>. <tag/请参阅/ <tt>definitionListTerm()</tt>, <tt>endList()</tt>, <tt>listItem()</tt>. </descrip> <sect2>definitionListTerm() <p> <descrip> <tag/目的/ 在定义列表中增加一项目. <tag/语法/ <tt>public void definitionListTerm ()</tt> <tag/描述/ 在定义列表中增加一项目. 目前列表的项目部份的文字应该在此方法被呼叫後并且在对应的 <tt>listItem</tt> 方法被呼叫前加入. <tag/请参阅/ <tt>definitionList()</tt>, <tt>listItem()</tt>. </descrip> <sect2>endList() <p> <descrip> <tag/目的/ 结束一列表. <tag/语法/ <tt>public void endList ()</tt> <tag/描述/ 本方法结束一列表.<em>注意,目前列表不能是巢状的</em>. <tag/请参阅/ <tt>definitionList()</tt>. </descrip> <sect2>listItem() <p> <descrip> <tag/目的/ 在列表中增加一项目. <tag/语法/ <tt>public void listItem ()</tt> <tag// <tt>public void listItem ( String item )</tt> <tag// <tt>public boolean listItem ( String term, String item )</tt> <tag/描述/ 在列表中增加一项目. 如果使用第一种形式,目前列表项目的文字应在此方法被叫後并在任何其它列表方法被呼叫前加入. 在第二及第三种形式中,<tt>item</tt> 文字被指定为方法的参数而不是在其後被加入. 第三种形式是定义列表专用并且同时指定列表的项目与定义文字部份. <tag/参数/ <descrip> <tag/item/ 此列表项目的文字. <tag/term/ 此定义列表的项目部份的文字. </descrip> <tag/请参阅/ <tt>definitionList()</tt>, <tt>definitionListTerm()</tt>, <tt>endList()</tt>. </descrip> <sect2>send() <p> <descrip> <tag/目的/ 送出此 HTML 讯息. <tag/语法/ <tt>public void send ()</tt> <tag/描述/ 送出此 HTML 讯息. </descrip> <sect2>title() <p> <descrip> <tag/目的/ 设定文件标题的文字. <tag/语法/ <tt>public void title ( String title )</tt> <tag/描述/ 设定此文件的标题文字. <tag/参数/ <descrip> <tag/title/ 此文件标题的文字. </descrip> <tag/请参阅/ <tt>author()</tt>. </descrip> <sect1>HTML_Test<label id="html-test-class"> <p> 这个类别提供一个如何使用 <tt>HTML</tt> 类别的例子以及一个用来确定 <em>Java CGI</em> 套件运作正常的测试程式. <sect2>成员摘要 <p> <code> main() // Program main(). </code> <sect2>请参阅 <p> <tt><ref id="html-class" name=HTML></tt>. <sect2>main() <p> <descrip> <tag/目的/ 提供 <tt>main()</tt> 方法. <tag/语法/ <tt>public static void main( String argv[] )</tt> <tag/描述/ 这是 CGI 程式的入口,返回在一 HTML 文件中可用的名称/数值配对与其现值的列表,并将每一名称/数值配对显示在一定义列表的元素里. <tag>参数 <descrip> <tag/argv[]/ 由 <tt>java.cgi</tt> 指令稿传入的参数.目前未使用. </descrip> </descrip> <sect1>Text<label id="text-class"> <p> <sect2>类别语法 <p> <tt>public abstract class Text</tt> <sect2>类别描述 <p> 本类别为 <tt><ref id="email-class" name=Email></tt> 与 <tt><ref id="html-class" name=HTML></tt> 的基础类别. 讯息以此类别的方法建立,并以衍生类别的方法完成并编排. <p> 这个类别位於 ``Orbits.net'' 包装中. <sect2>成员摘要 <p> <code> Text() // 建构子 add() // 加入文字到此物件 addLineBreak() // 加入分行符号 addParagraph() // 加入分段符号 </code> <sect2>请参阅 <p> <tt><ref id="email-class" name=Email></tt>, <tt><ref id="html-class" name=HTML></tt>. <sect2>add() <p> <descrip> <tag/目的/ 在此项目中加入文字. <tag/语法/ <tt>public void add ( char addition )</tt> <tag// <tt>public void add ( String addition )</tt> <tag// <tt>public void add ( StringBuffer addition )</tt> <tag/描述/ 在这个文字项目的内容中加入 <tt>addition</tt>. <tag/参数/ <descrip> <tag/addition/ 加入此文字项目的文字. </descrip> <tag/请参阅/ <tt>addLineBreak()</tt>, <tt>addParagraph()</tt>. </descrip> <sect2>addLineBreak() <p> <descrip> <tag/目的/ 强迫在目前文字位置分行. <tag/语法/ <tt>public void addLineBreak ()</tt> <tag/描述/ 在目前位置加入一分行符号. <tag/请参阅/ <tt>add()</tt>, <tt>addParagraph()</tt>. </descrip> <sect2>addParagraph() <p> <descrip> <tag/目的/ 起始一新的段落. <tag/语法/ <tt>public void add ()</tt> <tag/描述/ 在目前的文字位置起始一新的段落. <tag/请参阅/ <tt>add()</tt>, <tt>addLineBreak()</tt>. </descrip> <sect>未来的计画 <p> <itemize> <item> <tt>Email</tt> 类别的扩充: <descrip> <tag/Email( int capacity )/ 用来当我们知道需多少空间来储存讯息时. <tag/sendTo( String [] address )/ 增加原始电子邮件目的地的列表. <tag/sendCc( String address )/ 增加一个复制电子邮件目的地. <tag/sendCc( String [] address )/ 增加复制电子邮件目的地的列表. <tag/sendBcc( String address )/ 增加一个 Blind Carbon-Copy 的电子邮件目的地. <tag/sendBcc( String [] address )/ 增加 Blind Carbon-Copy 的电子邮件目的地列表 </descrip> </item> <item> <tt>HTML</tt> 类别的扩充: <descrip> <tag/HTML( int capacity )/ 用来当我们知道需多少空间来储存讯息时. <tag/public void unorderedList()/ 起始一无序列表. <tag/public void orderedList()/ 起始一有序列表. <tag/public void directoryList()/ 起始一目录列表. <tag/public void menuList()/ 起始一选单列表. <tag/void anchor( String anchorName )/ 指定一锚(anchor). <tag/void link( String url, String text )/ 指定一连结. <tag/void applet( String url, String altText )/ 指定一 applet 连结. </descrip> </item> <item> 允许巢状的 HTML 列表. </item> <item> 增加错误检查码以强迫修正 HTML 列表格式码的顺序. </item> <item> 环境变数资料的档案位置应能由 <tt>Makefile</tt> 设定. </item> <item> 除去在处理 GET 方法的资料传送时出现之假的空名称/数值对. </item> <item> 考虑让 <tt>CGI</tt> 实作 <tt>java.util.Enumeration</tt> 界面以依序地提供变数名称. </item> <item> 加入一 <tt>Test</tt> 类别,使用本套件中的每个方法. </item> <item> 说明 <tt>CGI_Test</tt>, <tt>Email_Test</tt> 与 <tt>HTML_Test</tt> 如何相互建立以提供侦错目的用的渐进测试. </item> <item> 说明如何测试使用本套件的每一个特徵. </item> </itemize> <sect>版本修改记录 <p> <sect1>由 0.4 到 0.5 的修改 <p> <itemize> <item> 更新文件与注解以反应新释出的版本。 </item> </itemize> <sect1>由 0.3 到 0.4 的修改 <p> <itemize> <item> 增添 <tt>HTML</tt> 类别提供的基本功能. </item> <item> 增加 <tt>HTML_Test</tt> 类别与 <tt>javahtmltest.html-dist</tt>. </item> <item> 增加 HTML 方法来处理定义列表. </item> </itemize> <sect1>由 0.2 到 0.3 的修改 <p> <itemize> <item> 加入 <tt>Text</tt> 与 <tt>Email</tt> 类别. <tt>HTML</tt> 也被加入,但此时只是一小部份而已. </item> <item> 将不同的类别放入包装中. 主要的类别在 <tt>Orbits.net.*</tt>,支援用的类别 <tt>Text</tt> 放在 <tt>Orbits.text.Text</tt>. </item> <item> 将 <tt>CGItest</tt> 改为 <tt>CGI_Test</tt>. </item> <item> 增加 <tt>Email_Test</tt> 类别. </item> </itemize> <sect1>由 0.1 到 0.2 的修改 <p> <itemize> <item> 环境变数被放入一暂存档中而不是勉强挤入 Java 解译器的命令列里. <tt>CGI</tt> 类别与 <tt>java.cgi</tt> 已被修改. </item> <item> 将 <tt>javacgitest.html</tt> 文件加入成为套件的一部份. </item> <item> 安装时由 <tt>make</tt> 所修改的档案全都以结尾 <em>-dist</em> 来命名. </item> </itemize> </article>