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>