|
級(jí)別: 初級(jí)
肖菁 (jing.xiao@chinacreator.com), 軟件工程師, 湖南省長沙鐵道學(xué)院科創(chuàng)計(jì)算機(jī)系統(tǒng)集成有限公司軟件中心
2004 年 1 月 01 日
本文將重點(diǎn)描述如何使用WSIF提供的WSDL擴(kuò)展將本地java類、EJB用WSDL文檔描述出來并且使用WSIF提供的統(tǒng)一方法進(jìn)行調(diào)用,并且詳細(xì)的介紹了WSIF中針對(duì)本地java類、EJB提供的WSDL擴(kuò)展功能。
WSIF 提供的API允許使用統(tǒng)一的方法調(diào)用可以用WSDL描述的服務(wù),而不需要了解該服務(wù)的實(shí)現(xiàn)機(jī)制和調(diào)用方法。WSIF中提供的WSDL擴(kuò)展允許編程者將本地java類、EJB、JMS的消息隊(duì)列、可以使用java連接器機(jī)制訪問的其他應(yīng)用虛擬成web服務(wù),然后使用統(tǒng)一的調(diào)用方法訪問這些服務(wù)。本文中作者將重點(diǎn)描述如何使用WSIF提供的WSDL擴(kuò)展將本地java類、EJB用WSDL文檔描述出來并且使用WSIF提供的統(tǒng)一方法進(jìn)行調(diào)用,并且詳細(xì)的介紹了WSIF中針對(duì)本地java類、EJB提供的WSDL擴(kuò)展功能。
1 WSIF簡介
WSIF是apache的web服務(wù)項(xiàng)目的一個(gè)子項(xiàng)目,目前版本是2.0,實(shí)際上是WSIF被提交給ASF后的第一次發(fā)布版本,命名為2.0是和以前非Apache發(fā)布的1.x版本相區(qū)別。
WSIF提供了一組簡單的API來調(diào)用web服務(wù)而不需要了解該web服務(wù)的實(shí)現(xiàn)方式,更深入的說,WSIF是一組基于WSDL文件的API,他調(diào)用可以用WSDL文件描述的任何服務(wù)。
WSIF中提供的API允許編程者通過WSDL描述內(nèi)容和web服務(wù)調(diào)用的抽象層打交道,而不是直接使用SOAP來調(diào)用web服務(wù)。編程者使用WSIF后就可以使用統(tǒng)一的編程模型來調(diào)用web服務(wù)而不需要了解該web服務(wù)是如何實(shí)現(xiàn)和被訪問的。
WSIF 2.0中里面提供了下列內(nèi)容的支持: SOAP(可以使用apache SOAP或者axis實(shí)現(xiàn))、本地java類、EJBs、JMS services和其它可以通過java connector訪問的應(yīng)用。WSIF規(guī)定了特別的WSDL擴(kuò)展使這些資源可以被當(dāng)成WSDL描述的服務(wù)訪問。
WSIF允許通過運(yùn)行時(shí)分析web服務(wù)描述的元數(shù)據(jù)來實(shí)現(xiàn)無stub或者動(dòng)態(tài)的調(diào)用一個(gè)web服務(wù)。他允許在運(yùn)行時(shí)將更新的綁定實(shí)現(xiàn)插入到WSIF中,他允許調(diào)用的服務(wù)在運(yùn)行時(shí)之前選擇自己的綁定實(shí)現(xiàn)。
WSIF具有以下幾個(gè)主要特征:
- 以WSDL為中心和服務(wù)的抽象定義(portType)打交道,隱藏實(shí)現(xiàn)細(xì)節(jié)(協(xié)議綁定和服務(wù)位置)
- 可插入式允許增加心得提供者使應(yīng)用可以通過修改WSDL就可以應(yīng)用新的web服務(wù)而不需要修改應(yīng)用的代碼
- 可擴(kuò)展很容易使用新的WSDL擴(kuò)展進(jìn)行試驗(yàn)
- 靈活性很容易定制很容易和JNDI結(jié)合使用是服務(wù)被提供的位置更加透明
2 本地java綁定的WSDL擴(kuò)展
WSIF中本地java綁定的WSDL擴(kuò)展允許將WSDL中的抽象功能直接映射到本地java類的實(shí)際功能實(shí)現(xiàn)上,這種擴(kuò)展意味著我們可以使用WSDL來描述一個(gè)本地Java類,然后使用WSIF提供的基于WSDL文件的服務(wù)調(diào)用方式來調(diào)用這個(gè)Java類。
在WSIF中,描述一個(gè)本地java類的WSDL的要素如下:
<definitions .... >
<!-- Java binding -->
<binding ... >
<java:binding/>
<format:typeMapping style="uri" encoding="..."/>?
<format:typeMap typeName="qname"|elementName="qname" formatType="nmtoken"/>*
</format:typeMapping>
<operation>*
<java:operation
methodName="nmtoken"
parameterOrder="nmtoken"?
returnPart="nmtoken"?
methodType="instance|static|constructor"? />?
<input name="nmtoken"? />?
<output name="nmtoken"? />?
<fault name="nmtoken"? />?
</operation>
</binding>
<service ... >
<port>*
<java:address
className="nmtoken"
classPath="nmtoken"?
classLoader="nmtoken"? />
</port>
</service>
</definitions>
|
下面的四個(gè)小節(jié)將詳細(xì)介紹這些擴(kuò)展的具體含義.
2.1 java:binding元素
使用該元素表示該綁定是一個(gè)java綁定
2.2 format:typemapping
format:typemapping元素允許定義WSDL消息中的抽象類型(在抽象服務(wù)描述中)和java類型的映射,他們表示同樣的信息。元素中的Style屬性用來規(guī)定目標(biāo)類型系統(tǒng)(比如:使用本地類型系統(tǒng)表示抽象信息);在java類型系統(tǒng)中,這個(gè)屬性的值必須是"java";這個(gè)屬性的使用允許這種擴(kuò)展被其他類型的綁定重用。Encoding屬性必須是一個(gè)URI,這個(gè)URI用來指示本地類型和抽象類型的協(xié)調(diào)方式。WSIF中的歷了一種特殊的encoding--"java" encoding-它告訴我們?nèi)绾卧赪SDL擴(kuò)展中的Java綁定中建立java類和一個(gè)抽象schema類型之間相對(duì)關(guān)系。Java encoding的詳細(xì)情況下面有介紹。使用encoding屬性允許我們建立自己的encoding來實(shí)現(xiàn)抽象類型和java類型之間的映射。
2.2.1 Java encoding
WSIF中的Java encoding是沒有詳細(xì)說明的,不需要詳細(xì)說明是encoding信息只有在java對(duì)象中包含的信息通過某種方式變換時(shí)才有--比如序列化到SOAP消息中或者轉(zhuǎn)化為其他類型系統(tǒng)中的某種表示。如果我們使用的WSIF消息只包含java類型系統(tǒng)中的類型,而且調(diào)用相應(yīng)的java服務(wù),那么我們只需要確保每個(gè)消息的部分使用java對(duì)象的正確類型表示就可以了(就像java綁定擴(kuò)展中的typemapping元素定義的那樣)。
當(dāng)然,這些特殊的需要也會(huì)存在,不過WSIF中目前還沒有提供,相信在WSIF的后續(xù)版本中會(huì)解決這個(gè)問題。
2.3 format:typemap
每個(gè)typemap元素將一種WSDL抽象類映射到一些方便的類型系統(tǒng)的某個(gè)類;在java綁定中,這種類型系統(tǒng)就是java類型系統(tǒng)。Typename屬性是被映射抽象類型的類型標(biāo)識(shí)符(必須是WSDL中已經(jīng)被預(yù)定義的schema類型或者是本W(wǎng)SDL中定義的某種類型)。Elementname屬性用來規(guī)定一個(gè)元素來代替一個(gè)類型(因?yàn)閃SDL消息的內(nèi)容可以被他們二者的任意一種描述)。Formtype屬性是對(duì)應(yīng)該抽象類型或者元素的java類型。它的值必須是某種原始java類型(char、byte、short、int、long、float、double)或者是某個(gè)java類的全名(包括包和類名).
2.4 java:operation
java:operation定義了抽象的WSDL操作和java方法之間的映射。Methodname屬性規(guī)定和抽象操作對(duì)應(yīng)的java方法的名字。Parameterorder屬性和抽象操作中的parameterorder規(guī)定類似而且重載了這個(gè)規(guī)定。它定義了服務(wù)調(diào)用時(shí)輸入?yún)?shù)的順序;在java綁定中,它定義了被調(diào)用方法的簽名。使用parameterorder屬性允許我們映射一個(gè)抽象操作和一個(gè)java方法,即使他們簽名對(duì)應(yīng)的參數(shù)順序不一致。Returnpart屬性和java方法的返回類型對(duì)應(yīng)的抽象輸出消息。Methodtype屬性規(guī)定被映射到的java方法是一個(gè)構(gòu)造器、一個(gè)靜態(tài)方法還是一個(gè)實(shí)例方法。
2.5 java:address
java:address元素是WSDL port元素的擴(kuò)展,它允許通過java綁定將一個(gè)java對(duì)象定以成服務(wù)的endpoint。這種方式定義的port只能是java綁定形式的。Classname屬性定了服務(wù)調(diào)用中要用到的java類的全名(包括包和類名,如:service.HellowWorld),可選擇的classpath屬性定義了調(diào)用之前需要設(shè)置的classpath,可選擇的classloader屬性定義了裝載服務(wù)類的類裝載器。如果是調(diào)用一個(gè)實(shí)例方法,服務(wù)使用者可以裝載和實(shí)例化一個(gè)服務(wù)類,這告訴服務(wù)提供者要保證每個(gè)服務(wù)類有一個(gè)public的無參數(shù)的構(gòu)造器可用。其他的被映射的java方法和構(gòu)造器也必須在服務(wù)類中是定以成public的。
WSDL中的其他元素來自于WSDL中預(yù)定義的元素,大家可以參考WSDL規(guī)范的相關(guān)內(nèi)容和說明。
好了,理論的東西講了這么多,現(xiàn)在給大家演示一個(gè)例子,看看如何在應(yīng)用中將本地的java類使用一個(gè)WSDL文件描述出來,并且使用WSIF的統(tǒng)一調(diào)用方法進(jìn)行調(diào)用。
3 EJB綁定的WSDL擴(kuò)展
WSIF中EJB綁定的WSDL擴(kuò)展允許將WSDL中的抽象功能直接映射到EJB的實(shí)際功能實(shí)現(xiàn)上,這種擴(kuò)展意味著我們可以使用WSDL來描述一個(gè)EJB,然后使用WSIF提供的基于WSDL文件的服務(wù)調(diào)用方式來調(diào)用這個(gè)EJB。
在WSIF中,描述一個(gè)EJB的WSDL的要素如下:
<definitions .... >
<!-- EJB binding -->
<binding ... >
<ejb:binding/>
<format:typeMapping style="uri" encoding="..."/>?
<format:typeMap typeName="qname"|elementName="qname" formatType="nmtoken"/>*
</format:typeMapping>
<operation>*
<ejb:operation
methodName="nmtoken"
parameterOrder="nmtoken"?
returnPart="nmtoken"?
interface="home|remote"? />?
<input name="nmtoken"? />?
<output name="nmtoken"? />?
<fault name="nmtoken"? />?
</operation>
</binding>
<service ... >
<port>*
<ejb:address
className="nmtoken"
jndiName="nmtoken"?
initialContextFactory="nmtoken"?
jndiProviderURL="url"?
archive="nmtoken"? />
</port>
</service>
</definitions>
|
分析它和本地java綁定的WSDL擴(kuò)展,可以看到他們的不同在于ejb:binding、ejb:operation、ejb:address三個(gè)元素,下面的三個(gè)小節(jié)將介紹這三個(gè)元素的定義。
3.1 ejb:binding元素
使用該元素表示該綁定是一個(gè)ejb綁定
3.2 ejb:operation
ejb:operation定義了抽象的WSDL操作和ejb接口中提供的方法之間的映射。Methodname屬性規(guī)定和抽象操作對(duì)應(yīng)的java方法的名字。Parameterorder屬性和抽象操作中的parameterorder規(guī)定類似而且重載了這個(gè)規(guī)定。它定義了服務(wù)調(diào)用時(shí)輸入?yún)?shù)的順序;在ejb綁定中,它定義了被調(diào)用方法的簽名。使用parameterorder屬性允許我們映射一個(gè)抽象操作和一個(gè)java方法,即使他們簽名對(duì)應(yīng)的參數(shù)順序不一致。Returnpart屬性和java方法的返回類型對(duì)應(yīng)的抽象輸出消息。EjbInterface屬性用于規(guī)定被映射的方法由EJB的遠(yuǎn)程(Remote)還是本地(home)接口提供。系統(tǒng)默認(rèn)被映射的方法由EJB的遠(yuǎn)程(Remote)接口提供。
3.3 ejb:address
java:address元素是WSDL port元素的擴(kuò)展,它允許通過ejb綁定將一個(gè)ejb對(duì)象定義成服務(wù)的endpoint。這種方式定義的port只能是ejb綁定形式的。Classname屬性定了服務(wù)調(diào)用中要用到的EJB的本地接口類的全名(包括包和類名,如:org.vivianj.wsif.HelloWorldHome),可選擇的aechive屬性定義了調(diào)用之前需要設(shè)置的classpath,可選擇的classloader屬性定義了裝載服務(wù)類的類裝載器。所有被映射的方法必須在服務(wù)類中是定義成public的。InitialContextFactory(初始化上下文的工廠類)和jndiProviderURL(JNDI提供者的URL)屬性用于指定完成EJB的jndi查詢時(shí)需要設(shè)置的相關(guān)參數(shù)。
4 HelloWorld實(shí)例
在我們的例子中,我們提供了兩種實(shí)現(xiàn),一種是本地類HelloWorld.java,一種是一個(gè)Session EJB,他們實(shí)現(xiàn)同樣的功能。
本地類一個(gè)方法(getHelloString),它根據(jù)傳入的參數(shù)返回一個(gè)字符串say Hello To + %輸入的參數(shù)%,該類的實(shí)現(xiàn)代碼如下:
4.1 HelloWorld.java實(shí)例
//HelloWorld.java
package service;
public class HelloWorld
{
public String getHelloString(String param){
return "Say hello to : " + param;
}
}
|
Session EJB的實(shí)現(xiàn)請(qǐng)查看文章后面的工程(wsif-ejb.jar)中的實(shí)現(xiàn),下面是該ejb實(shí)現(xiàn)類的代碼。
4.2 EJB實(shí)現(xiàn)類的代碼
package org.vivianj.wsif;
import java.rmi.RemoteException;
public class HelloWorldBean implements javax.ejb.SessionBean {
private javax.ejb.SessionContext mySessionCtx;
public javax.ejb.SessionContext getSessionContext() { return mySessionCtx;}
public void setSessionContext(javax.ejb.SessionContext ctx) { mySessionCtx = ctx; }
public void ejbCreate() throws javax.ejb.CreateException {}
public void ejbActivate() {}
public void ejbPassivate() {}
public void ejbRemove() {}
public String getHelloString(String param){
String result = "Say hello to : " + param;
return result;
};
}
|
4.3 如何編寫WSDL文檔來描述本地類
現(xiàn)在我們將根據(jù)WSIF中java綁定的WSDL擴(kuò)展來使用WSDL文檔描述這個(gè)java類,下面是作者根據(jù)WSIF中的localjava例子中的WSDL文檔編寫的一個(gè)WSDL文檔(HelloWorld.wsdl),它描述了我們編寫的HelloWorld.java類,供大家參考:
<?xml version="1.0" ?>
<definitions targetNamespace="http://wsifservice.helloworld/"
xmlns:tns="http://wsifservice.helloworld/"
xmlns:typens="http://wsiftypes.helloworld.ient.localjava/"
xmlns:xsd="http://www./1999/XMLSchema"
xmlns:soap="http://schemas./wsdl/soap/"
xmlns:format="http://schemas./wsdl/formatbinding/"
xmlns:java="http://schemas./wsdl/java/"
xmlns="http://schemas./wsdl/">
<!-下面這一段定義了服務(wù)調(diào)用中使用的消息-->
<message name="getHelloStringRequestMessage">
<part name="param" type="xsd:string"/>
</message>
<message name="getHelloStringResponseMessage">
<part name="resp" type="xsd:string"/>
</message>
<!-- port type declns -->
<portType name="HelloWorld">
<operation name="getHelloString">
<input name="getHelloStringRequest" message="tns:getHelloStringRequestMessage"/>
<output name="getHelloStringResponse" message="tns:getHelloStringResponseMessage"/>
</operation>
</portType>
<!-- binding declns -->
<binding name="JavaBinding" type="tns:HelloWorld">
<java:binding/>
<format:typeMapping encoding="Java" style="Java">
<format:typeMap typeName="xsd:string" formatType="java.lang.String" />
</format:typeMapping>
<operation name="getHelloString">
<java:operation
methodName="getHelloString"
parameterOrder="param"
methodType="instance" />
<input name="getHelloStringRequest"/>
<output name="getHelloStringResponse"/>
</operation>
</binding>
<!-- service decln -->
<service name="HelloWorldService">
<port name="JavaPort" binding="tns:JavaBinding">
<java:address className="service.HelloWorld"/>
</port>
</service>
</definitions>
|
其中的binding元素是我們重點(diǎn)關(guān)注的:
- 它的第一個(gè)子元素就是java:binding,表示這是一個(gè)java綁定類型
- format:typeMapping的元素和含義請(qǐng)參考上面關(guān)于java綁定的WSDL擴(kuò)展的相關(guān)內(nèi)容
- format:typeMap定義了java.lang.String和xsd:String之間的類型映射
- java:operation定義了WSDL中的抽象方法getHelloString和java方法中的getHelloString方法的映射。它的parameterorder屬性規(guī)定了輸入?yún)?shù)的順序,methodtype屬性表示這是一個(gè)實(shí)例方法調(diào)用。它的子元素input和output定了該方法調(diào)用用到的輸入輸出參數(shù)等
service元素的java:address子元素表示這是一個(gè)綁定到本地java類的port.
其他的元素都是WSDL規(guī)范中關(guān)于web服務(wù)的相關(guān)預(yù)定義元素,請(qǐng)大家參考WSDL規(guī)范中的相關(guān)定義。
4.4 如何編寫WSDL文檔來描述EJB
現(xiàn)在我們將根據(jù)WSIF中ejb綁定的WSDL擴(kuò)展來使用WSDL文檔描述這個(gè)EJB,下面是作者針對(duì)HelloWorld實(shí)例編寫的一個(gè)WSDL文檔(EJBWsdl.wsdl),它描述了我們編寫的HelloWorld實(shí)例EJB,供大家參考:
<?xml version="1.0" ?>
<definitions targetNamespace="http://wsifservice.helloworld/"
xmlns:tns="http://wsifservice.helloworld/"
xmlns:typens="http://wsiftypes.rvice.ejb/"
xmlns:xsd="http://www./1999/XMLSchema"
xmlns:soap="http://schemas./wsdl/soap/"
xmlns:format="http://schemas./wsdl/formatbinding/"
xmlns:ejb="http://schemas./wsdl/ejb/"
xmlns="http://schemas./wsdl/">
<!-- message declns -->
<message name="GetHelloStringRequestMessage">
<part name="param" type="xsd:string"/>
</message>
<message name="GetHelloStringResponseMessage">
<part name="resp" type="xsd:string"/>
</message>
<!-- port type declns -->
<portType name="HelloWorld">
<operation name="getHelloString">
<input name="GetHelloStringRequest" message="tns:GetHelloStringRequestMessage"/>
<output name="GetHelloStringResponse" message="tns:GetHelloStringResponseMessage"/>
</operation>
</portType>
<!-- binding declns -->
<binding name="EJBBinding" type="tns:HelloWorld">
<ejb:binding/>
<format:typeMapping encoding="Java" style="Java">
<format:typeMap typeName="xsd:string" formatType="java.lang.String" />
</format:typeMapping>
<operation name="getHelloString">
<ejb:operation
methodName="getHelloString"
parameterOrder="param"
interface="remote"
returnPart="resp" />
<input name="GetHelloStringRequest"/>
<output name="GetHelloStringResponse"/>
</operation>
</binding>
<!-- service decln -->
<service name="HelloStringService">
<port name="EJBPort" binding="tns:EJBBinding">
<ejb:address className="org.vivianj.wsif.HelloWorldHome"
jndiName="ejb/HelloWorld"
initialContextFactory="weblogic.jndi.WLInitialContextFactory"
jndiProviderURL="t3://202.197.40.36:7001"
archive="e:/wsifTest/ejbbinding/wsifejb.jar;D:/bea/weblogic81/server/lib/weblogic.jar" />
</port>
</service>
</definitions>
|
其中的binding元素是我們重點(diǎn)關(guān)注的:
- 它的第一個(gè)子元素就是ejb:binding,表示這是一個(gè)ejb綁定類型
- format:typeMapping的元素和含義請(qǐng)參考上面關(guān)于ejb綁定的WSDL擴(kuò)展的相關(guān)內(nèi)容
- format:typeMap定義了java.lang.String和xsd:String之間的類型映射
- ejb:operation定義了WSDL中的抽象方法getHelloString和EJB中的getHelloString方法的映射。它的parameterorder屬性規(guī)定了輸入?yún)?shù)的順序,interface屬性表示這個(gè)方法由EJB的遠(yuǎn)程方法提供。它的子元素input和output定了該方法調(diào)用用到的輸入輸出參數(shù)等。
service元素的ejb:address子元素表示這是一個(gè)綁定到ejb的port. InitialContextFactory和jndiProviderURL定義了初始化工廠和提供者的URL。
4.5 使用WSIF提供的API調(diào)用
好了,現(xiàn)在我們已經(jīng)將自己編寫的本地類、EJB用WSDL描述出來了,接下來的工作將是演示如何使用WSIF提供的API通過使用我們編寫的WSDL文檔來調(diào)用這個(gè)服務(wù)。
下面這段代碼是作者編寫的調(diào)用這兩個(gè)服務(wù)的Run.java, 供大家參考。它需要我們的WSDL文件名作為參數(shù),處理結(jié)果是將服務(wù)調(diào)用的返回結(jié)果打印在控制臺(tái)上。
//Run.java
package dynamic;
import javax.xml.namespace.QName;
import org.apache.wsif.WSIFMessage;
import org.apache.wsif.WSIFOperation;
import org.apache.wsif.WSIFPort;
import org.apache.wsif.WSIFService;
import org.apache.wsif.WSIFServiceFactory;
public class Run {
public static void main(String[] args) throws Exception {
// 第一個(gè)參數(shù)是 WSDL文件的位置和名字
// 創(chuàng)建服務(wù)工廠(service factory)
WSIFServiceFactory factory = WSIFServiceFactory.newInstance();
WSIFService service =
factory.getService(
args[0],
null,
null,
"http://wsifservice.helloworld/",
"HelloWorld");
// 參數(shù)http://wsifservice.helloworld/對(duì)應(yīng)于我們WSDL文檔中的targetNamespace
//參數(shù)HelloWorld對(duì)應(yīng)于WSDL文檔中的porttype
// 參數(shù)類型映射
service.mapType(
new QName("http://wsifservice.helloworld", "param"),
Class.forName(
"java.lang.String"));
// 獲得port
WSIFPort port = service.getPort();
// 創(chuàng)建操作(operation)
WSIFOperation operation = port.createOperation("getHelloString");
// 創(chuàng)建和該操作調(diào)用相關(guān)的輸入/輸出/錯(cuò)誤信息
WSIFMessage input = operation.createInputMessage();
WSIFMessage output = operation.createOutputMessage();
WSIFMessage fault = operation.createFaultMessage();
// 組裝輸入信息
input.setObjectPart("param", "xiaojing");
// 執(zhí)行調(diào)用
if (operation.executeRequestResponseOperation(input, output, fault)) {
// 調(diào)用成功,從返回信息中獲取我們需要的信息
// message
String zipInfo =
(String) output.getObjectPart("resp");
// resp就是我們的WSDL文檔中的output對(duì)應(yīng)的消息(message元素)中的參數(shù)(part元素)的名字
System.out.println(zipInfo);
} else {
System.out.println("Invocation failed");
// 調(diào)用失敗,處理錯(cuò)誤信息
}
}
}
|
[注] 調(diào)用這兩個(gè)服務(wù)的代碼實(shí)際上是一模一樣的,除了輸入的WSDL文件名不同。這也是WSIF的重要特性:
- 通過WSDL文件調(diào)用服務(wù),不管他是如何實(shí)現(xiàn)和被訪問的。
- 盡可能的將修改限制在WSDL文件中而不需要修改應(yīng)用代碼
4.6 編譯運(yùn)行
4.6.1 設(shè)置環(huán)境變量
由于編譯和運(yùn)行這個(gè)程序需要將大量的.jar文件設(shè)置到classpath中,所以請(qǐng)各位參考下載的WSIF包中的classpath.bat和lcp.bat編寫自己的腳本來實(shí)現(xiàn)環(huán)境變量的設(shè)置。后面的下載的包里面有作者編寫的環(huán)境變量設(shè)置腳本,供大家參考。
4.6.2 運(yùn)行
設(shè)置好環(huán)境變量后,編譯程序,然后就可以使用下面的命令來執(zhí)行這個(gè)程序了:
java dynamic.Run HelloWorld.wsdl
|
它執(zhí)行后的顯示結(jié)果如下圖:
4.7 可改進(jìn)的地方
如果各位有心的話,應(yīng)該可以發(fā)現(xiàn),其實(shí)我們編寫的Run.java中的有些參數(shù)仍然來自于我們的WSDL文檔、和客戶應(yīng)用基本沒有關(guān)聯(lián)(比如:factory.getService方法調(diào)用的第四個(gè)參數(shù)和第五個(gè)參數(shù),他們來源于WSDL中的一些元素,而且和客戶應(yīng)用基本沒有關(guān)聯(lián)),所以如果你可以做的話,你可以自己編寫一個(gè)基于SAX的XML文檔解析類,將這些和WSDL關(guān)聯(lián)而和應(yīng)用代碼不很密切的內(nèi)容從WSDL中直接取值,而不是依賴于編程者的輸入。
5 復(fù)雜類型
如果被輸入的參數(shù)或者返回的參數(shù)不是java的原始類型,那么我們的類型映射就沒有這么簡單了。大家可以參考WSIF中提供的localjava的例子,它的返回類型都用到了 一個(gè)address的類型,它是該實(shí)例中用到的一個(gè)自定義的類型,對(duì)應(yīng)于一個(gè)java類,WSDL文檔的編寫也和一般的不同,請(qǐng)參考WSIF中提供的AddressBook.wsdl實(shí)例。不過一點(diǎn)可以給大家提示的是,編寫好了wsdl文檔后,其中復(fù)雜類型對(duì)應(yīng)的java類不需要自己編寫,可以使用Axis提供的wsdl2java功能來生成,命令的使用類似于:java org.apache.axis.wsdl.WSDL2Java (WSDL-file-URL),詳細(xì)的幫助請(qǐng)大家參考Axis項(xiàng)目的用戶指導(dǎo)(User Guide)
6 相關(guān)工具
研究到這一步的時(shí)候,作者想起來另外兩個(gè)提供了類似功能的工具:AXIS和WSAD(Websphere studion application develop).
- Axis中的Java2wsdl功能可以為一個(gè)本地類生成將它發(fā)布為web服務(wù)的WSDL文件,只需要設(shè)置一些參數(shù)而已,這個(gè)作者經(jīng)過研究發(fā)現(xiàn)原來WSIF中已經(jīng)包含了Axis的jar文件,應(yīng)該是WSIF直接繼承了這項(xiàng)功能,所以應(yīng)該是使用了同樣的原理,只是使用范圍不同而已。
- WSAD中提供的向?qū)Чδ苤С謱ava類、EJB等內(nèi)容通過向?qū)Оl(fā)布成web服務(wù),相信也是采用了和這個(gè)相同的原理
7 總結(jié)
WSIF允許使用者用WSDL文件描述本地java類、EJB,也就是將本地java類、EJB虛擬成一個(gè)Web服務(wù),然后使用WSIF提供的API調(diào)用這個(gè)服務(wù),達(dá)到類似于通過服務(wù)調(diào)用本地類、EJB的效果。
本文中作者詳細(xì)的介紹了WSIF中提供的對(duì)java、EJB綁定的WSDL的支持,如何編寫WSDL文檔來描述和映射一個(gè)本地的java類、EJB,給出了編寫的WSDL文檔的實(shí)例和簡單的說明,同時(shí)給出了如何通過WSIF提供的統(tǒng)一的調(diào)用方式通過WSDL文檔調(diào)用本地類、EJB的例子。通過實(shí)例大家可以看到我們實(shí)現(xiàn)了服務(wù)調(diào)用和服務(wù)實(shí)現(xiàn)的分離,任何服務(wù)實(shí)現(xiàn)和相關(guān)的映射基本上只會(huì)影響到服務(wù)的實(shí)現(xiàn)和WSDL的修改,不會(huì)影響到服務(wù)調(diào)用段代碼的修改。
|