日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

编写CGI小结(Java)

發(fā)布時間:2024/4/17 java 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 编写CGI小结(Java) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

轉(zhuǎn)載請注明出處:http://blog.csdn.net/hungryhuang/article/details/6601684。

? ? ? ?由于Carl要用到我的程序,我們便合作工作。但是他寫的程序是Python的,我寫的程序是Java的,必須得找一種方式進(jìn)行通信。盡管有Jython這些東西,但是Carl認(rèn)為還是CGI最簡便。于是,前陣子開始學(xué)學(xué)CGI怎么弄。剛開始,覺得好像也不是很難,但是后來進(jìn)展沒有預(yù)期的順利。最后,由于學(xué)院的服務(wù)器有CGI模塊但是不允許隨便跑CGI,實(shí)驗(yàn)室服務(wù)器又裝的是FastCGI,感覺麻煩,最后Carl說還是用socket吧... - - |||。

? ? ? ?整體來說,用CGI進(jìn)行通信這個計(jì)劃算是破產(chǎn)了。雖然是很老舊、基本都不會再用的東西了,但是由于對我來說是新東西,還是很好奇,沒有實(shí)現(xiàn),自然是一種惋惜。雖然最后沒能用上CGI,但是個人覺得如果學(xué)院服務(wù)器讓用戶自己跑CGI的話,應(yīng)該還是沒問題的。無論怎樣,還是記錄下一些基本知識,免得以后又忘了。


? ? ? ?CGI年代久遠(yuǎn),不過卻實(shí)現(xiàn)了動態(tài)網(wǎng)頁。CGI,準(zhǔn)確說,應(yīng)該是種協(xié)議(或者說接口),它使得server中的程序(cgi script)能夠通過標(biāo)準(zhǔn)I/O流(STDIN和STDOUT,比如在Java語言里就是System.in和System.out,在C里面就是printf等,只要是能夠進(jìn)行標(biāo)準(zhǔn)I/O流讀寫的程序,都可以用來實(shí)現(xiàn)CGI)讀取到所需的信息和輸出信息給瀏覽器,而這些所要從客戶端讀取的信息則是包含在某些已經(jīng)被定義好的環(huán)境變量中,我們只需要讀取這些環(huán)境變量,自然就能獲取想要的值了(這也就是CGI這個借口為我們所做的事)。而通常所說的CGI,也有可能泛指CGI程序,即CGI script,是開發(fā)者自己所寫的、處理用戶請求的程序。
? ? ? ? 總體來說,過程是這樣的:
? ? ? ? 1. 服務(wù)器接受到請求
? ? ? ? 2. 服務(wù)器發(fā)現(xiàn)這個請求是需要一個CGI程序來進(jìn)行處理
? ? ? ? 3. 服務(wù)器建立一個環(huán)境,這個運(yùn)行環(huán)境里有一些變量,也就是所謂的CGI程序所需要的環(huán)境變量
? ? ? ? 4. 服務(wù)器在這個環(huán)境下啟動相應(yīng)的CGI程序
? ? ? ? 5. CGI程序解析自己想要的環(huán)境變量來獲取所提交的請求信息
? ? ? ? 6. CGI程序?qū)@些請求信息做相應(yīng)的處理
? ? ? ? 7. CGI程序?qū)⑾鄳?yīng)的結(jié)果輸出到標(biāo)準(zhǔn)輸出STDOUT,此結(jié)果將被輸出到用戶端,呈現(xiàn)給用戶結(jié)果。
? ? ? ? 8. CGI程序執(zhí)行完畢,退出程序。


? ? ? ?比較詳細(xì)來說,原理大概是這樣的:
? ? ? ?1. 客戶端在瀏覽某個網(wǎng)頁的時候,提交表單(form)。而表單的action則指定了要處理該表單的CGI程序,比如:?
? ? ? ? ? ? ? ? ? ?<html>
? ? ? ? ? ? ? ? ? ?<body>
? ? ? ? ? ? ? ? ? ? ? ?<form action="/cgi-bin/plus.cgi" method="GET">
? ? ? ? ? ? ? ? ? ? ? ? ? ?<input name="m" size="5">
? ? ? ? ? ? ? ? ? ? ? ? ? ?<input name="n" size="5"><br>
? ? ? ? ? ? ? ? ? ? ? ? ? ?<input type="submit" values="提交">
? ? ? ? ? ? ? ? ? ? ? ?</form>
? ? ? ? ? ? ? ? ? ?</body>
? ? ? ? ? ? ? ? ? ?</html>
? ? ? ? 上面的程序中,action="/cgi-bin/plus.cgi" 的意思就是說“這個表單里的數(shù)據(jù),都交給plus.cgi這個程序處理了,然后它處理完這些數(shù)據(jù)后,再把結(jié)果返回給瀏覽器”。
? ? ? ? ?需要說明的是,plus是一個可執(zhí)行文件的文件名,比如可能是一個shell文件(例如 plus.sh),其后綴不一定是.cgi。那么為什么要取在這里取名.cgi呢?原因是這樣能說明,這個表單處理,是通過一個類型為cgi的程序進(jìn)行處理,或者說,通過cgi這種方式讓這個可執(zhí)行文件對提交的數(shù)據(jù)進(jìn)行處理。一般來說,出于安全考慮,不是任何用戶都有權(quán)限去寫一個自己的cgi程序然后上傳到服務(wù)器、讓該服務(wù)器去運(yùn)行的(比如我們學(xué)院的服務(wù)器就不行,哎...)。而只有放在服務(wù)器指定目錄(一般為cgi-bin)下的可執(zhí)行文件,才會被被視為是cgi程序,才能被執(zhí)行。而一般人是無法訪問這個目錄的。
? ? ? ??
? ? ? ? 2. 然后,name為“m”和“n”的這兩個變量以及他們的值,就通過某個環(huán)境變量輸入到CGI程序中,由CGI程序去進(jìn)行該CGI程序所指定的處理了。GET和POST獲取“m”和“n”的方式有所不同。如果提交方法是GET的話,那么GET所提交的內(nèi)容則被包含在名為QUERY_STRING的環(huán)境變量中,當(dāng)?shù)玫竭@個環(huán)境變量的值后,將其內(nèi)容解析出來就可以得到name/value這樣的值對了,就可以進(jìn)行相應(yīng)的處理了。而POST的話,則需要從標(biāo)準(zhǔn)輸入流STDIN里面讀取數(shù)據(jù),而這些數(shù)據(jù)到底有多少呢?這個則需要通過讀取CONTENT_LENGTH這個環(huán)境變量的值來知道。
? ? ? ? 像在C語言里面,可以通過getenv函數(shù)來直接獲取環(huán)境變量的值,比如:getenv("QUERY_STRING"), ?getenv("CONTENT_LENGTH")等等。Perl可能要算是寫CGI的最佳語言,但是不會Perl,此處略過。另外,由于我的程序是用Java寫的,就使得讀取環(huán)境變量的方式有點(diǎn)特殊,因?yàn)镴ava是沒有直接獲取這些環(huán)境變量的函數(shù)的。Java為何不能直接訪問環(huán)境變量?簡單說,因?yàn)镴ava內(nèi)部還有一個屬于System這個類的屬性。因此,我們一個System.getProperty獲取的是Java中這個System類的屬性的,而不是環(huán)境變量的。這些System的屬性也是以name/value這樣的形式來存儲一些Java運(yùn)行環(huán)境的信息的。因而,額外的環(huán)境變量(或者說屬性信息)需要用指令java -D的形式,詳見后面的wrapper程序。
? ? ? ? 常用的環(huán)境變量有:REQUEST_METHOD,QUERY_STRING,CONTENT_LENGTH,PATH_INFO。其他的有:SERVER_SOFTWARE,SERVER_NAME,GATEWAY_INTERFACE,SERVER_PROTOCOL,SERVER_PORT,PATH_TRANSLATED,SCRIPT_NAME,REMOTE_HOST,REMOTE_ADDR,AUTH_TYPE,REMOTE_USER,REMOTE_IDENT,CONTENT_TYPE。如果現(xiàn)在忘記這些是干嘛的了...額...google下吧...
? ? ? ? 現(xiàn)在,我們已經(jīng)讀取到了所想要的環(huán)境變量。但是,這些環(huán)境變量的值,是需要我們進(jìn)行解析的,因?yàn)楫?dāng)初在傳給我們的時候,就是進(jìn)行了URL編碼的(URL encode)。比如,如果我們提交的表單是GET類型的話,再提交完信息后,可以在地址欄看來類似這樣的url地址:http://www.xxxxxxx.edu/cgi-bin/plus.cgi?m=5&n=6。其中,“m=5&n=6”就是被編碼的字符串,也就是我們想要獲取的值。而“http://www.xxxxxxx.edu/cgi-bin/plus.cgi”是處理該表單的cgi程序的地址。“?”說明后面的字符串(即“m=5&n=6”)是傳入的參數(shù)。不難看出,在編碼的時候,類似于這樣的規(guī)則“name1=value1&name2=value2&name3=value3”。此外,非西文的字符串將被“%XX”所代替,空格將被“+”代替。具體地,去參考URL encode的相關(guān)資料。
? ? ? ?如何解析這些麻煩的字符串,不需要自己再動手去寫,網(wǎng)上有很多這樣的函數(shù)庫,各種語言。直接用網(wǎng)上現(xiàn)成的函數(shù)庫來解析就行了。就Java來說,推薦cgi_lib.java這個庫。很方便,應(yīng)用也很廣泛,文件也很小。其中函數(shù)的功能是跟cgi_lib.pl一樣的。


? ? ? ?3. 解析字符串后,我們可以知道變量m的值為5,變量n的值為6。然后就可以在CGI程序中進(jìn)行相應(yīng)的處理了。自己想怎么處理就怎么處理。比如,此處是想處理加法,則在自己的CGI程序里實(shí)現(xiàn)m和n的加法即可。


? ? ? ?4. 處理完了數(shù)據(jù),需要將結(jié)果呈現(xiàn)給瀏覽器端的用戶。這個簡單,直接用STDOUT就行了。比如,C語言用printf,Java語言用System.out.println之類的。但是需要注意的是,首先輸出的必須是"Content-type: text/plain"(也就是MIME頭信息,告訴server它隨后的輸出是以純ASCII文本的形式),然后下面空一行(必須空一行),再直接打印出要呈現(xiàn)給用戶的html語句。比如,在Java里面,就是:
? ? ? ? System.out.println("Content-type: text/plain");
? ? ? ? System.out.println("");
? ? ? ? 比如,要測驗(yàn)自己是否有權(quán)限可以寫一個CGI放在服務(wù)器上運(yùn)行,則可以寫一個最簡單的CGI程序,該程序暫時不處理任何來自用戶的請求,只是輸出"Hello, world"。
? ? ? ? shell程序可以寫成:
? ? ? ? #!/bin/sh
? ? ? ? echo "Content-type: text/html"
? ? ? ? echo ""
? ? ? ? echo "<html>"
? ? ? ? echo "<body>"
? ? ? ? echo "<h1>Hello, world</h1>"
? ? ? ? echo "</body>"
? ? ? ? echo "</html>"


? ? ? ? C語言可以寫成:
? ? ? ? #include<stdio.h>
? ? ? ? void main(void){
? ? ? ? ? ? printf("Content-type: text/html\n");
? ? ? ? ? ? printf("\n");
? ? ? ? ? ? printf("<html>\n");
? ? ? ? ? ? printf("<body>\n");
? ? ? ? ? ? printf("<h1>Hello, world</h1>\n");
? ? ? ? ? ? printf("</body>");
? ? ? ? ? ? printf("/<html>");
? ? ? ? }


? ? ? ? 這樣,在客戶端運(yùn)行就會呈現(xiàn)出<h1>大小的“Hello, world”了。


Java的特別注意:
? ? ? ? 1.Java讀取環(huán)境變量,只能通過-D的option來加以讀取。
? ? ? ? 2.Java生成的.class文件(比如java_plus.class),這不是一個通常意義上的可執(zhí)行文件,這個文件只是說通過JVM可以執(zhí)行起來。而CGI程序是一個直接可以執(zhí)行的文件。因此,我們需要寫一個wrapper,將這個.class文件封裝起來。當(dāng)調(diào)用這個wrapper程序的時候,這個wrapper程序能通過Java指令運(yùn)行該.class文件。
? ? ? ? 結(jié)合上訴兩點(diǎn),則我們可以寫一個shell文件當(dāng)做wrapper程序,如下:
? ? ? ? #!/bin/sh
? ? ? ? java \
? ? ? ? -Dcgi.content_type=$CONTENT_TYPE \
? ? ? ? -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 \
? ? ? ? java_plus
? ? ? ? 然后將上面的文件保存為plus.sh,并且放在指定的目錄(比如cgi-bin)即可。這樣,當(dāng)表單提交新的時候,就會到這個目錄中(因?yàn)楹缶Y名為cgi)去尋找名為plus的文件,然后執(zhí)行這個文件。而在java_plus這個文件中,我們用System.getProperty("cgi.query_string")就可以訪問到QUERY_STRING這個環(huán)境變量了。


推薦一些鏈接:

http://www.jmarshall.com/easy/cgi/

http://www.eli.sdsu.edu/courses/spring96/cs596/notes/andrew/cgi.html

http://www.javaworld.com/javaworld/jw-01-1997/jw-01-cgiscripts.html

http://apps.hi.baidu.com/share/detail/18814484

http://www.jaguarpc.com/forums/showthread.php?t=2553

http://httpd.apache.org/docs/current/howto/cgi.html



?

至于FastCGI,這個效率比傳統(tǒng)CGI高很多。但是,比較麻煩,需要用循環(huán),還要設(shè)置端口什么的,就沒動手搞那個,只是看了下相關(guān)資料。還是放在這里吧。

http://www.phpchina.com/download/handbook/linux-html/1272.html

http://www.20cn.net/ns/wz/net/data/20030615005558.htm

http://www.fastcgi.com/devkit/doc/fcgi-java.htm

http://www.citycat.ru/doc/FastCGI/fcdk/index.html

http://hi.baidu.com/coffeefoam/blog/item/1446493be749f3e814cecbb8.html

?

?

web應(yīng)用中動態(tài)部分的java和cgi實(shí)現(xiàn)原理的簡單總結(jié)

http://my.oschina.net/hulubo/blog/56330

一、初始web
最初知道網(wǎng)站是用html寫的,靜態(tài)的,會動的那個顯示效果,內(nèi)容完全沒變,只是有時候移動了,有時候隱藏了。
這個時候,我認(rèn)為:
瀏覽器是一個html的解釋器和http的解釋器的合體。
服務(wù)器是一個接收http請求,并可以根據(jù)請求中指定的文件(無論是地址欄寫的,還是超鏈接發(fā)送的)找到服務(wù)器對應(yīng)的文件,把文件中的內(nèi)容以http的格式返回給瀏覽器。

不過聽說表單是可以提交給后臺處理的,也就是內(nèi)容可以根據(jù)人工輸入而改變的。但是這個過程一直不知道是什么樣。

二、java的動態(tài)網(wǎng)站
后來學(xué)習(xí)了java,知道用tomcat和jsp/servlet就可以實(shí)現(xiàn)動態(tài)交互的網(wǎng)站,比如提交個表單,后臺處理一下,然后返回一個結(jié)果。但是文件不是html了,而jsp了,或者直接后臺的java類了,既然瀏覽器沒有變,那么后臺返回的內(nèi)容一定還是html格式的內(nèi)容,無論是jsp還是servlet都是需要tomcat(或者apache+tomcat等)翻譯成html格式的靜態(tài)文件。其中tomcat可以內(nèi)部劃分為web服務(wù)器和應(yīng)用服務(wù)器(即j2ee的容器)。

那么流程大概是這樣的:
1、瀏覽器請求一個地址,
2、web服務(wù)器通過地址的格式判斷,如果后綴是html等靜態(tài)文件就直接返回文件內(nèi)容,
3、如果后綴是jsp就發(fā)送給應(yīng)用服務(wù)器處理,容器會將相應(yīng)的jsp文件翻譯為servlet(即java類),
4、如果后綴是其他非常規(guī)靜態(tài)文件和jsp,那么也會發(fā)送給容器,容器檢查web.xml中的servlet定義是否包含了這個路徑,如果有則調(diào)用相應(yīng)的servlet,
5、調(diào)用servlet之前,容器會在啟動時進(jìn)行一系列j2ee規(guī)范中的session-config、context-param,welcom-file-list等預(yù)處理來準(zhǔn)備提供服務(wù),接收請求之前會運(yùn)行l(wèi)istener,filter等對請求做預(yù)處理,這些都不是本文要關(guān)心的。
6、終于在第3或第4步等待這么久的servlet要處理了,web服務(wù)器傳給容器的地址,就好像一個標(biāo)準(zhǔn)輸入的文本,容器監(jiān)聽程序讀取地址,然后解析對應(yīng)的類,并嘗試調(diào)用類的對象。容器管理所有servlet對象的生命周期,對象保存在容器中重復(fù)使用,容器根據(jù)注冊在web.xml中的類尋找對象,如果沒有,則會創(chuàng)建一個該類的對象并運(yùn)行其init方法,當(dāng)有請求時,調(diào)用對象的service方法。并將servlet的輸出流(HttpServletResponse.getWriter())作為返回的結(jié)果,并且完全按照html格式輸出。
7、容器將結(jié)果返回給瀏覽器,瀏覽器解析http報(bào)文,解釋html文件,顯示。

三、cgi是什么
除了java之外,還有很多語言都可以做動態(tài)網(wǎng)站,比如asp、.net,雖然只看過一眼,猜想大概和java的類似,有自己的容器負(fù)責(zé)處理。但是其他語言貌似都是用cgi實(shí)現(xiàn),那么cgi是什么,雖然百度(鄙視我吧)了一下定義,完全沒搞清楚,繼續(xù)找吧。沒有寫過cgi,只能順藤摸瓜的半猜半看了。
cgi其實(shí)是一套web服務(wù)器和各種語言通信的協(xié)議,Common Gateway Interface通用網(wǎng)關(guān)接口,其實(shí)web服務(wù)器需要通信的東西不多。
1、主要是告訴后臺程序,傳了什么參數(shù)過來(除了用戶手工填寫的參數(shù),還有瀏覽器相關(guān)、http協(xié)議相關(guān)的一些參數(shù)),后臺程序如果通過主程序參數(shù)傳入非常不通用而且復(fù)雜,所以cgi規(guī)定了一套環(huán)境變量,讓http請求的相關(guān)參數(shù)全部存在環(huán)境變量中,那么所有后臺語言都可以引用環(huán)境變量的參數(shù)值。
2、解決了傳參問題,那么就是如何運(yùn)行了,在apache(web服務(wù)器)中,可以在httpd.conf中配置程序執(zhí)行器,例如perl語言就用perl.exe(windows中),web服務(wù)器會用瀏覽器請求的地址生成本地文件的路徑,作為perl.exe的運(yùn)行參數(shù)。當(dāng)然如果命令行需要其他的參數(shù),也可以在web服務(wù)器中配置。
3、執(zhí)行完后,后臺程序輸出到標(biāo)準(zhǔn)輸出流的結(jié)果會被web服務(wù)器捕獲(當(dāng)然也是html格式的),封裝成http包發(fā)送給瀏覽器。
4、瀏覽器解析顯示。

可以看出,cgi每次請求都重新執(zhí)行后臺程序的解析工作,進(jìn)程不像java一樣在容器中可以重復(fù)利用。有個叫fastcgi的就是解決這個問題的,它是一個進(jìn)程管理器,讓進(jìn)程能重復(fù)利用。

?

?

?

=========http://gaodi2002.blog.163.com/blog/static/232076820106215131828/

C語言cgi程序在apache上的實(shí)現(xiàn)??

本文介紹使用apache實(shí)現(xiàn)C語言寫的cgi程序。
必要條件,安裝apache。
首先建立C程序,這里就不多介紹。參照前面的文章或者其它的參考書籍。
建立文件hello.c,內(nèi)容如下:
#include <stdio.h>
int main()
{
?? printf("Content-type:text/html\n\n");
?? printf("<html>");
?? printf("<head><title>welcome to c cgi.</title></head><body>");
?? printf("你好:世界<br/>");
?? printf("</body></html>");
}
編繹hello.c,生成hello.exe。把hello.exe文件拷到 apache安裝/cgi-bin/ 目錄下。
然后配置 apache 配置文件 httpd.conf。在配制文件中找到
AddHandler cgi-script .cgi 在這一行后面加上 .exe,并且去掉前邊的#
最后在瀏覽器中輸入 http://localhost/cgi-bin/hello.exe,回車。
在瀏覽器中將顯示:你好:世界。
通過index.html調(diào)用cgi
index.html 文件如下:
<HTML>
<HEAD>
<HEAD>
<BODY>
<FORM ACTION=http://localhost/cgi-bin/cgi.exe METHOD=POST>
<INPUT TYPE=submit VALUE=OK>
</FORM>
</BODY>
</HTML>
在瀏覽器中輸入 http://localhost/index.html,回車。
點(diǎn)擊ok按鈕,調(diào)用cgi程序?yàn)g覽器顯示:你好:世界。

總結(jié)

以上是生活随笔為你收集整理的编写CGI小结(Java)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。