明輝手游網(wǎng)中心:是一個免費提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺!

用JavaScript編寫HelloWorld應(yīng)用(轉(zhuǎn))

[摘要]你是一個渴望永遠站在技術(shù)最前沿的Java開發(fā)者嗎?軟件產(chǎn)業(yè)風(fēng)云變幻,你渴望把握Web的未來,更重要的是,如何把自己數(shù)年的Java經(jīng)驗發(fā)揮到極致。要尋找這些問題的答案,你不必走得太遠,答案就在于SOAP。 SOAP(簡單對象訪問協(xié)議)是一種利用XML編碼數(shù)據(jù)的有線協(xié)議,它為Java的平臺無關(guān)性、可移...
你是一個渴望永遠站在技術(shù)最前沿的Java開發(fā)者嗎?軟件產(chǎn)業(yè)風(fēng)云變幻,你渴望把握Web的未來,更重要的是,如何把自己數(shù)年的Java經(jīng)驗發(fā)揮到極致。要尋找這些問題的答案,你不必走得太遠,答案就在于SOAP。

SOAP(簡單對象訪問協(xié)議)是一種利用XML編碼數(shù)據(jù)的有線協(xié)議,它為Java的平臺無關(guān)性、可移植性帶來了更高層次的協(xié)同操作能力。在這個關(guān)于SOAP的系列文章的第二篇中,我介紹了Apache SOAP。作為SOAP規(guī)范的實現(xiàn)之一,Apache SOAP簡化了SOAP應(yīng)用的構(gòu)造。我們曾經(jīng)用Apache SOAP構(gòu)造了兩個簡單的HelloWorld服務(wù),以及調(diào)用這些服務(wù)的sayHelloTo()方法的客戶程序。我們看到,雖然創(chuàng)建SOAP服務(wù)相當簡單,但客戶程序必須完成許多額外的工作,例如它必須設(shè)置Call對象,調(diào)用Call對象的invoke()方法,然后分析作為調(diào)用結(jié)果返回的Response對象。

其實,用Apache SOAP創(chuàng)建SOAP服務(wù)的過程還可以變得更簡單,唯一的前提是:你必須懂得規(guī)定的幾種腳本語言之一。對我來說——以及對大多數(shù)Java開發(fā)者來說,幸運的是,這些腳本語言中包含了JavaScript。確實不錯,在Apache SOAP中,你可以用JavaScript創(chuàng)建SOAP服務(wù)。本文要介紹的就是用JavaScript創(chuàng)建SOAP服務(wù)的具體做法。

一、重新構(gòu)造Apache SOAP
Apache SOAP的腳本支持建立在Bean Scripting Framework(BSF,Bean腳本框架)的基礎(chǔ)之上。BSF原先由IBM開發(fā),現(xiàn)在作為一個源代碼開放的工程發(fā)行,它使得Java程序能夠運行用其他語言編寫的腳本,也使得其他腳本語言能夠使用已有的Java類。Apache SOAP利用了BSF的前一種能力。從Apache網(wǎng)站下載的標準二進制版本不支持腳本。具體地說,soap.jar不包含org.apache.soap.server.InvokeBSF類,而這個類是Apache SOAP和BSF的結(jié)合點和接口。Apache SOAP的開發(fā)者知道,并非每一個使用SOAP的人都需要BSF,也并非每一個人都安裝了腳本引擎,所以在soap.jar中省略了腳本支持。要想用腳本編寫SOAP服務(wù),你必須從源代碼重新構(gòu)造以便引入InvokeBSF類。

首先要從http://xml.apache.org/dist/soap/下載源代碼(soap-src-2.0.zip)。然后,把下載得到的文件解壓縮到Apache SOAP所安裝的目錄。在我這里,它是E:驅(qū)動器的根目錄。完成后,你將在soap_2-0目錄下得到一個src子目錄,子目錄中包含Apache SOAP的所有源代碼。重新從源代碼構(gòu)造Apache SOAP之前,你還必須下載必需的BSF jar文件。在ftp://ftp.mozilla.org/pub/js/可以找到一個。請結(jié)合Mozilla的JavaScript引擎Rhino使用它,Rhino可以從http://www.mozilla.org/rhino/download.html下載一個ZIP文件得到。我把這個文件解壓縮到E:盤根目錄下,最終得到一個包含了Rhino的E:\rhino目錄,我們感興趣的是它的js.jar。

接下來,你需要一個實際執(zhí)行重新構(gòu)造操作的工具,即Ant。Ant也是一個Apache的軟件工程,它是一個基于Java的工具。Ant實際上和創(chuàng)建Web服務(wù)器Tomcat的工程同屬一個工程,即Jakarta。在Ant中,所有構(gòu)造信息,例如構(gòu)造目標、依賴關(guān)系等,都通過XML配置文件指定,這是Ant獨一無二的特點。此外,Ant是可擴展的。請參見本文最后“參考資源”部分收錄的文章,了解如何充分發(fā)揮Ant的潛能。你可以從參考資源提供的鏈接下載Ant,然后解開壓縮(我把它放入了C:盤的根目錄)。

現(xiàn)在,從Apache SOAP安裝目錄執(zhí)行如下命令:

set
CLASSPATH=E:\jakarta-tomcat\lib\servlet.jar;E:\xerces-1_2_0\xerces.jar;
E:\soap-2_0\lib\bsf.jar
C:\build\bin\ant


由于上面的命令沒有指定一個XML配置文件,Ant批命令文件將在當前目錄(在我這里,是E:\soap_2-0)中尋找一個名為build.xml的文件。Apache SOAP提供了這個文件。打開這個文件可以看到,只有當com.ibm.bsf.BSFManager在classpath中時,InvokeBSF類才會編譯。這就是我把bsf.jar(它包含了BSFManager類)放入類路徑的原因。把新構(gòu)造出來的soap.jar文件從build\lib子目錄復(fù)制到lib子目錄(我建議修改原來的soap.jar文件進行備份)。最后,把bsf.jar和js.jar加入到Web服務(wù)器的類路徑。

大功告成!現(xiàn)在你可以開始用腳本編寫SOAP服務(wù)了。

二、用JavaScript編寫HelloWorld應(yīng)用
現(xiàn)在,我們用JavaScript重新編寫第二篇文章的HelloWorld服務(wù)。服務(wù)程序的完整代碼如下:

function sayHelloTo(name)
{
return "Hello " + name + ", How are you?";
}


還有比這更容易的事情嗎?不過,不要讓這簡單易行欺騙了你。事實上,你可以在服務(wù)程序里進行相當復(fù)雜的處理。例如,你可以從腳本代碼訪問任何標準的Java類。請看下面經(jīng)過修改的腳本代碼,它輸出服務(wù)器的時間:

function sayHelloTo(name)
{
var today = new java.util.Date();
java.lang.System.out.println("Today is " + today.toString());
return "Hello " + name + ", How are you?";
}


另外,你還可以導(dǎo)入和使用自己的任意Java類。例如,我們可以修改腳本代碼,讓它使用Name JavaBean:

importClass(Packages.hello.Name);
function sayHelloTo(name)
{
var today = new java.util.Date();
java.lang.System.out.println("Today is " + today.toString());
var beanName = new Name();
beanName.setName("John");

java.lang.System.out.println(beanName.getName());
return "Hello " + name + ", How are you?";
}


三、部署服務(wù)
在使用JavaScript版本的服務(wù)之前,首先要部署它。正如本系列文章的第二篇所介紹的,在Apache SOAP中部署服務(wù)有兩種辦法:使用Web界面的管理工具,或者從命令行部署服務(wù)。下面我們來看看兩種辦法的具體操作過程。

3.1 使用Web界面的管理工具
要使用Web界面的管理工具,用瀏覽器打開http://localhost:8080/apache-soap/admin。點擊窗口左邊的Deploy按鈕。記住,ID輸入框用來設(shè)置對象ID,SOAP基礎(chǔ)設(shè)施利用對象ID把RPC(遠程過程調(diào)用)請求關(guān)聯(lián)到SOAP服務(wù)。每一個Apache SOAP服務(wù)都必須有一個對象ID,而且這個對象ID必須在該服務(wù)器上部署的所有服務(wù)之間唯一。把ID設(shè)置成urn:Hello,這個ID也就是我們在第二篇文章中為服務(wù)設(shè)置的對象ID。

把Scope輸入框設(shè)置成application;仡櫼幌拢琒cope輸入框用來指定響應(yīng)調(diào)用請求的服務(wù)實例的生存時間(請參考第二篇文章中的更多說明)。

在Methods輸入框中輸入當前部署的服務(wù)允許調(diào)用的方法名字,多個方法名字之間以空白字符分隔。我們的服務(wù)只支持一個方法,即sayHelloTo()。

由于服務(wù)用JavaScript實現(xiàn),而不是象第二篇文章那樣用Java實現(xiàn),所以Provider Type輸入框應(yīng)該填script。相應(yīng)地,Java Provider輸入框(包括Provider Class和Static輸入框)不必填寫。但現(xiàn)在必須填寫Script Provider輸入框,選擇JavaScript(Rhino)作為腳本語言。由于我們將在Script文本輸入框中提供腳本正文,所以現(xiàn)在不用填寫Script Filename輸入框。把下面的腳本代碼復(fù)制到Script輸入框:

importClass(Packages.hello.Name);
function sayHelloTo(name)
{
var today = new java.util.Date();
java.lang.System.out.println("Today is " + today.toString());
var beanName = new Name();
beanName.setName("John");

java.lang.System.out.println(beanName.getName());
return "Hello " + name + ", How are you?";
}


現(xiàn)在滾動到屏幕的最下面,點擊表單下面的Deploy按鈕(不是窗口左邊的Deploy按鈕)。要驗證服務(wù)已經(jīng)成功部署,點擊窗口左邊的List按鈕。這時,urn:Hello服務(wù)應(yīng)該在服務(wù)清單中出現(xiàn)。點擊這個服務(wù),確認所有信息都與剛才輸入的吻合。

3.2 從命令行部署服務(wù)
要從命令行部署服務(wù),所有部署信息必須放入一個XML部署描述器文件。下面是我用來部署該服務(wù)的XML部署描述器文件:

<isd:service xmlns:isd="http://xml.apache.org/xml-soap/deployment"
id="urn:Hello">
<isd:provider type="script" scope="Application" methods="sayHelloTo">
<isd:script language="javascript">
importClass(Packages.hello.Name);
function sayHelloTo(name)
{
var today = new java.util.Date();
java.lang.System.out.println("Today is " + today.toString());
var beanName = new Name();
beanName.setName("John");

java.lang.System.out.println(beanName.getName());
return "Hello " + name + ", How are you?";
}
</isd:script>
</isd:provider>
</isd:service>


和第二篇文章用到的部署描述器文件相比,這里主要的不同在于把提供者類型設(shè)置成了script而不是java。由于這個原因,部署描述器文件不再指定一個Java類,而是提供了服務(wù)的腳本代碼。

部署服務(wù)之前應(yīng)當確保Web服務(wù)器已經(jīng)啟動。下面的代碼顯示了如何部署服務(wù):

java org.apache.soap.server.ServiceManagerClient
http://localhost:8080/apache-soap/servlet/rpcrouter deploy
DeploymentDescriptor.xml


DeploymentDescriptor.xml是前面介紹的包含部署描述信息的XML文件。要驗證服務(wù)已經(jīng)成功部署,執(zhí)行下面的命令:

java org.apache.soap.server.ServiceManagerClient
http://localhost:8080/apache-soap/servlet/rpcrouter query urn:Hello


這時,我們應(yīng)該看到和DeploymentDescriptor.xml文件一樣的內(nèi)容。

四、測試
我們用第二篇文章提供的客戶程序Client.java來測試HelloWorld服務(wù)。為什么可以用同一個客戶程序訪問JavaScript編寫的服務(wù)呢?因為客戶程序完全不會在乎服務(wù)用什么語言編寫。只要服務(wù)能夠理解SOAP請求,能夠返回SOAP應(yīng)答,客戶程序不會關(guān)注服務(wù)用什么方式實現(xiàn);仡櫼幌,下面就是我用來運行hello.Client的批命令文件:

set
CLASSPATH=E:\soap-2_0\samples\;E:\soap-2_0\lib\soap.jar;
E:\xerces-1_2_0\xerces.jar
java hello.Client Tarak


觀察Web服務(wù)器的控制臺窗口,每次運行客戶程序的時候,我們都可以看到當前的日期和輸出“John”。

■ 結(jié)束語
在這篇文章中,我介紹了Apache SOAP實現(xiàn)所提供的腳本語言支持。為什么說它很重要呢?只要分析一下為何Web開發(fā)如此流行。在我看來,一個關(guān)鍵的原因在于Web開發(fā)已經(jīng)成熟,幾乎任何人都能夠用HTML和JavaScript之類的簡單腳本語言構(gòu)造出復(fù)雜的Web頁面。類似地,在Web開發(fā)的服務(wù)器端,人們可以使用JSP這類易學(xué)但強大的腳本語言。我認為這種推理同樣適用于SOAP開發(fā)。如果SOAP想要挺進主流,獲得絕大部分人的支持,那么它應(yīng)該盡量地簡化。Apache SOAP加入對腳本的支持正是為了這個目標;它顯著地擴展了創(chuàng)建SOAP服務(wù)的開發(fā)者的范圍。

不過,不要忘了還有另一個因素需要考慮:客戶端開發(fā)者,即調(diào)用SOAP服務(wù)的開發(fā)者。如前所述,Apache SOAP的客戶端開發(fā)者比較“吃虧”,反而增加了一些原本不必做的工作。因此,在本系列文章的下一篇也即最后一篇中,我將介紹一個框架,它以Java 2平臺1.3版本新引入的動態(tài)代理類為基礎(chǔ),使得創(chuàng)建客戶程序就象創(chuàng)建SOAP服務(wù)一樣簡單直觀。(下一篇)
■ 參考資源

W3C的SOAP 1.1規(guī)范

http://www.w3.org/TR/SOAP/
下載Apache SOAP:

http://xml.apache.org/dist/soap/
關(guān)于IBM SOAP工程的更多信息:

http://www.alphaworks.ibm.com/tech/soap4j
關(guān)于Mozilla Rhino的更多信息:

http://www.mozilla.org/rhino/
關(guān)于Ant的更多信息:

http://jakarta.apache.org/ant/index.html
利用Java和Ant自動化構(gòu)造過程(JavaWord,2001年10月):

http://www.javaworld.com/jw-10-2000/jw-1020-ant.html
下載Ant:

http://jakarta.apache.org/builds/jakarta-ant/release/v1.2/bin/