一、什麼是動態內容
大多數熱門Web網站都從網路廣告業務獲利。 Web頁面中的廣告空間是有限的,為了讓廣告投資物有所值,廣告客戶不僅必須在很小的廣告空間內塞入大量的信息,而且還要確保廣告能夠吸引用戶的注意力。在目前大多數的網站上,放入Web頁面的橫幅廣告一般由伺服器在建構頁面的同時生成,我們無法把新的廣告動態地插入到已經發送出去的頁面。 如果要顯示新的廣告,唯一的方法就是重新刷新頁面。我們可以用程式設計的方法來刷新頁面,例如:
使用瀏覽器視窗物件的setTimeOut函數定期刷新頁面。但是,用這種方法刷新廣告時,使用者會很明顯地感覺到頁面刷新過程;同時,要確定一個合適的刷新頻率也很困難。
將頁面的過期時間設定為數秒時間,使得無論何時輸入焦點轉到該頁面(即瀏覽器被啟動)時,瀏覽器就會重新下載該頁面。
一些大型網站,如yahoo.com和msn.com,都已經採用了這些技術。這兩種方法都有各自的優點和缺點。在只使用Java的情況下,我們完全可以透過網路程式設計和一些介面程式設計工作來實現橫幅廣告的刷新系統,但必須解決下載時間過長和刷新延遲的問題。
二、用Java實現內容推送
結合JavaScript幀間通訊和一個管理網路通訊的Java Applet,我們能夠用推送技術解決這個問題。在這樣一個系統中,Java Applet的任務是連接伺服器並監聽內容更新。一旦接收了新的內容,Applet就會建構出顯示這些新內容的HTML程式碼,呼叫一個JavaScript函數並將包含新內容的HTML傳遞給JavaScript函數。 JavaScript函數運用DHTML和DOM技術,把頁面中一個
Web伺服器只在80埠監聽連線請求。因此,除了Web伺服器之外,我們還需要一個接受Applet的Socket連線請求的網路應用程式服務。這個網路應用程式服務定時地查詢資料庫,把改動資料發布(推播)到所有已經連接的Applet。由於運用了隱藏幀和JavaScript的幀間通訊功能,我們能夠從使用者面前隱藏大多數JavaScript邏輯。
在這整個處理過程中,最困難的任務是Java Applet與JavaScript程式碼之間的通訊。 Netscape提供了一個稱為netscape.javascript.JSObject的類別。要使用這個對象,請加入一個包含特殊「MAYSCRIPT」屬性的Applet標記:
JSObject的方法允許Applet與文件物件互動以及呼叫JavaScript命令。例如,把下面的程式碼放入Applet,我們就能夠存取視窗物件:
import netscape.javascript.*; public class MyApplet extends java.applet.Applet{ private JSObject mainwin; public void init(){ mainwin = JSObject.getWindow( this); } }
取得JSObject引用後,我們就能夠存取文件視窗對象,並透過JSObject的eval()方法呼叫JavaScript函數。
三、用DHTML更新頁面
在把來自Applet的新內容寫入文件時,為了不影響原來已經存在的內容,我們可以使用HTML的
對於IE以及Netscape 6,這個HTML標記是:
// 所有要更新的內容必須用id標識
對於Netscape 4.x版本,這個HTML標記是:
雖然我們可以透過引用適當的ID,從Applet直接更新HTML內容,但為了清楚起見,我們將把更新HTML程式碼的程式邏輯放入JavaScript函數。下面的JavaScript程式碼把瀏覽器的型別儲存到ie變數:
applnname=navigator.appName; if(applnname=="Microsoft Internet Explorer") { ie=true; } else { ie=false; }
Applet從新資料建構出HTML程式碼,把它儲存到JavaScript變數content,然後呼叫assignData()方法。內容資料可以是從純HTML到XML到二進位資料的任何東西。
// 根據瀏覽器類型呼叫適當的方法function assignData() { if(ie) {explore();} else {navig(); } }
如果瀏覽器是IE或Netscape 6,Applet呼叫explore()方法:
//content是一個javascript變量,它以HTML格式描述了需要//顯示的新資料function explore() { iexplorer.innerHTML=content; }
如果瀏覽器是Netscape 4.0或更高版本,Applet呼叫navig()方法:
function navig() { document.netscapev.document.write(““ + content + ““); document.netscapev. document.close(); }
四、通訊過程
在伺服器端,一個ImageAppliation.java類別的實例回應Socket連線請求,並為每個新的連線請求建立一個新的執行緒。為了簡化程式碼,每個執行緒只檢查資料檔案是否改變。如果資料檔案已經改變,則執行緒讀取檔案內容,並將新的資料傳送給已經連接的Applet(範例應用程式將整個檔案傳送給Applet)。
在客戶端,一個隱藏幀包含了ImageApplet.java這個Applet,因此用瀏覽器的查看HTML原始碼功能是無法看到Applet標記的。 Applet實作了連接伺服器(下載該Applet的來源伺服器)的功能,並實作了一個簡單的通訊協定。建立與伺服器的連線之後,Applet接收來自伺服器的數據,建構出HTML程式碼,並呼叫JavaScript函數把資料傳入文件:
public void upDateHTML(String str){ //data是表單的名字, //quote是一個JavaScript變數//str是新建構出來的HTML程式碼mainwin.eval("document.data.quote.value=“" + str + "“"); mainwin.eval("javascript:assignData()"); return; }
netscape.javascript.JSObject完成Applet到JavaScript的通信,不同版本的客戶端瀏覽器需要不同的版本。你可以下載得到為Netscape提供的壓縮類別檔案java40.jar。 IE已經帶有JSObject類,但有點難找。你可以搜尋$windows$JavaPackages目錄尋找包含JSObject類別的ZIP檔案。
伺服器把ImageArrayElement.java類別的實例透過toString()方法串列化成為字串傳送給Applet。伺服器從資料檔案建構出各個對象,呼叫toString()方法,連接得到代表所有對象的字串,最後發送結果字串。而在另一端,Applet接收並解析這個字串,重新建構出各個ImageArrayElement物件。這裡之所以用一個長字串的形式發送數據,是因為這種方法只需要很簡單的處理過程,使得用戶能夠以接近實時的速度立即得知數據的變化;但是,我們也可以用另外一種方法,即以向量的形式發送物件。
在一個正式運作的應用程式中,你一般應該讓新資料插入目前頁面的流程透明。但在範例應用中,為了讓程式運行過程更加直觀,它將在新內容到達的時候提示使用者。
推播技術最主要的優點就是應用伺服器只把那些改變的資料傳送到網絡,這使得延遲減到了最少。由於這個Applet負責完成的工作非常少(不涉及使用者介面,這部分工作由瀏覽器負責),所以Applet體積很小,裝載速度非常快。
五、如何運行本文實例
要測試本文範例應用,你的機器上必須安裝有Web伺服器和JDK 1.7或更高版本。
安裝重點:
解開ZIP壓縮檔並安裝到Web伺服器預設根目錄。
對於IIS伺服器,預設根目錄是Inetputwwwroot
對於jsdk2.1所帶的免費伺服器,預設目錄是<安裝目錄>webpages
解開壓縮檔案之後,所有檔案都會安裝到
把下面幾行程式碼加入預設頁面。每種伺服器都有自己的預設頁面,IIS的預設頁面是“default.htm”,請參閱Web伺服器文件以了解具體說明:
運行應用程式的步驟:
開啟一個DOS窗口,進入<預設Web目錄>/exp,執行「java ImageApplication」。系統將顯示「Server started listening at port 6011」。注意確保classpath環境變數指向了目前工作目錄。
啟動Web伺服器。
開啟瀏覽器輸入下面的URL: http://localhost:8080 。該URL將開啟Web伺服器的預設頁面,它應該有一個「Java based dynamic Ad-Banner」連結。點擊這個連結就啟動了本文的範例應用程式。
用Notepad開啟「/exp/images.txt」文件,複製並貼上一行內容,儲存文件。你可以立即看到系統顯示一個JavaScript視窗提示內容更新。關閉JavaScript窗口,頁面將顯示新的內容。
請從這裡下載本文實例的完整程式碼,411 KB/u/info_img/2009-06/20/pushweb.zip