監(jiān)理公司管理系統(tǒng) | 工程企業(yè)管理系統(tǒng) | OA系統(tǒng) | ERP系統(tǒng) | 造價(jià)咨詢管理系統(tǒng) | 工程設(shè)計(jì)管理系統(tǒng) | 甲方項(xiàng)目管理系統(tǒng) | 簽約案例 | 客戶案例 | 在線試用
X 關(guān)閉

EJB 2.1中實(shí)現(xiàn)Web Service

申請(qǐng)免費(fèi)試用、咨詢電話:400-8352-114

AMTeam.org

EJB 2.1中實(shí)現(xiàn)Web Service

EJB2.1(Enterprise JavaBeans 2.1)正式推薦版本已經(jīng)出臺(tái),它產(chǎn)生的動(dòng)力主要是Enterprise JavaBeans對(duì)支持Web Service的需求,同時(shí)也是因?yàn)镸icrosoft .NET的發(fā)布,它對(duì)J2EE或者說(shuō)對(duì)Java技術(shù)來(lái)說(shuō)已經(jīng)構(gòu)成了巨大威脅。在新版本的EJB2.1中,主要的變化主要集中在基于SOAP和WSDL的Web Service上。EJB已經(jīng)成為一種新的Web Service平臺(tái)。它對(duì)Web Service的支持主要體現(xiàn)在三個(gè)新的Web Service API上:分別是JAX-RPC(Java API for XML-RPC,它基本上是通過(guò)SOAP實(shí)現(xiàn)的Java RMI,為RPC格式的SOAP消息提供遠(yuǎn)端接口)、SAAJ(SOAP API with Attachments for Java,它模仿SOAP消息的結(jié)構(gòu),同時(shí)也有功能有限的消息分發(fā)能力)和JAXM(Java API for XML Messaging,它類似于JMS,提供發(fā)送和接收SOAP消息的消息架構(gòu)),利用它們可以實(shí)現(xiàn)與其它類型的Web Service進(jìn)行通訊,而且還允許無(wú)序的會(huì)話Bean和消息驅(qū)動(dòng)的Bean來(lái)作為Web Service使用,使它們能夠被任何與 SOAP1.1兼容的客戶端所訪問(wèn)。例如:使用SOAP,我們就可以從其它平臺(tái)Web Service來(lái)調(diào)用無(wú)序的會(huì)話Bean的方法,象微軟的.NET,Perl,Apache Axix和其他的語(yǔ)言和平臺(tái)。EJB2.1中新的Web Service功能能夠提供一種前所未有的跨平臺(tái)互操作性,它主要是建立在兩個(gè)嶄新的J2EE SOAP工具包JAX-RPC和JAXM。

Web Service代表了分布式計(jì)算的最新潮流,可能是自1995年Java的出現(xiàn)和1998年XML出現(xiàn)以來(lái)最重要的技術(shù)了。其實(shí),給Web Service下一個(gè)準(zhǔn)確的定義是很難的,因?yàn)閃eb Service并不是任何特殊技術(shù)或者平臺(tái)所特有的,Web Service是一種網(wǎng)絡(luò)應(yīng)用程序,以XML形式的文檔,使用SOAP和WSDL進(jìn)行信息交換。要更好地理解這句話的含義,你必須先理解SOAP和WSDL,下面是有關(guān)這方面的定義:

SOAP:簡(jiǎn)單對(duì)象訪問(wèn)協(xié)議(Simple Object Access Protocol),是在W3C的支持下,由Microsoft,IBM和其他公司開發(fā)的,基于XML格式的一種協(xié)議,它是可伸縮和可擴(kuò)展的,不象以前的DCE RPC, CORBA IIOP, Java RMI-JRMP以及DCOM,它已經(jīng)被幾乎所有的開發(fā)廠商所認(rèn)可和接受。

WSDL:Web服務(wù)描述語(yǔ)言(Web Service Description Language),也是在W3C的支持下,由Microsoft,IBM和其他公司開發(fā)的,XML格式的語(yǔ)言,用來(lái)對(duì)Web Service進(jìn)行描述,包括期望的消息格式類型、所使用的Internet協(xié)議和Web Service的Internet地址。

其實(shí),Web Service代表了一種新的分布式對(duì)象技術(shù),它和CORBA IIOP和Java RMI很相似,但也有許多差異,最大的差異應(yīng)該就是真正的平臺(tái)無(wú)關(guān)性。盡管Java RMI和CORBA IIOP都聲稱自己是平臺(tái)無(wú)關(guān)的,但實(shí)際上,它們都需要它們自己的平臺(tái)。要使用Java RMI,你需要一個(gè)Java虛擬機(jī)和Java編程語(yǔ)言,對(duì)使用其它語(yǔ)言的開發(fā)者如Visual Basic或C++來(lái)說(shuō),Java RMI并不是平臺(tái)無(wú)關(guān)的。CORBA IIOP也是有局限性的,IIOP協(xié)議通常需要一個(gè)特定的架構(gòu)如CORBA ORB,也只有少數(shù)幾個(gè)廠商支持CORBA。另一方面,Web Service著重描述信息交換的協(xié)議,而不是著重描述對(duì)這些協(xié)議的實(shí)現(xiàn),換句話說(shuō),你可以用任何語(yǔ)言,在任何平臺(tái)上,以任何你自己喜歡的方式來(lái)創(chuàng)建Web Service。

Web Service另外一個(gè)好處就是,不象其它的分布式對(duì)象體系,它建立在現(xiàn)有的技術(shù)架構(gòu)的基礎(chǔ)之上,因此大多說(shuō)廠商很容易實(shí)現(xiàn)。SOAP和WSDL都是基于XML的,而XML已經(jīng)被廣泛支持,XML解析器在幾乎每一種開發(fā)語(yǔ)言中都有,因此,處理SOAP消息和WSDL文檔的基礎(chǔ)已經(jīng)存在了。此外,Web Service消息通常是通過(guò)TCP/IP進(jìn)行交換的,也已經(jīng)被幾乎所有的平臺(tái)和語(yǔ)言所支持。

JAX-RPC和EJB

JAX-RPC(Java API for XML-RPC)實(shí)質(zhì)上就是通過(guò)SOAP訪問(wèn)的Java RMI。它和“本地的”Java RMI (Java RMI-JRMP)和Java RMI-IIOP很象,但是它是以SOAP作為通訊協(xié)議。要實(shí)現(xiàn)JAX-RPC,最低要求是必須對(duì)通過(guò)HTTP訪問(wèn)的SOAP支持RPC編碼,但是,我們?nèi)匀豢梢蕴峁?duì)其他編碼方式、消息格式和Internet協(xié)議的支持。JAX-RPC能夠被用來(lái)從會(huì)話、實(shí)體和消息驅(qū)動(dòng)的Bean來(lái)調(diào)用Web Service的操作。JAX-RPC能夠用來(lái)訪問(wèn)其它平臺(tái)的Web Service。例如:一個(gè)無(wú)序的會(huì)話Bean可能會(huì)使用JAX-RPC來(lái)調(diào)用.NET Web Service的方法。如下圖所示:

 

每個(gè)EJB開發(fā)商都會(huì)提供自己對(duì)JAX-RPC的實(shí)現(xiàn),但它們之間的差別是很小的,主要是因?yàn)樗械膶?shí)現(xiàn)都必須遵照J(rèn)AX-RPC規(guī)范,JAX-RPC能夠當(dāng)作客戶端API來(lái)訪問(wèn)其它的Web Service,但是,它同時(shí)也是一個(gè)被稱作“EndPoint接口”的新型企業(yè)Bean接口。當(dāng)JAX-RPC當(dāng)作客戶端API的時(shí)候,會(huì)話、實(shí)體或者消息驅(qū)動(dòng)的Bean能夠使用它與其它平臺(tái)的Web Service交換消息。JAX-RPC定義了三種編程模型:Generated Stub、Dynamic Proxy和DII(Dynamic Invocation Interface),我們?cè)贓JB環(huán)境中常用的Generated Stub模型。

如果使用JAX-RPC去訪問(wèn)Web Service,那么,這個(gè)Web Service必須發(fā)行一個(gè)WSDL文檔,EJB開發(fā)商提供的JAX-RPC工具包產(chǎn)生Java RMI接口和實(shí)現(xiàn)WSDL文檔所描述的Web Service操作的Stub,一旦Stub和接口創(chuàng)建出來(lái)之后,我們就可以把它們與企業(yè)Bean的JNDI ENC(Environment Naming Context)進(jìn)行綁定,然后與 Web Service進(jìn)行通信。

WSDL把訪問(wèn)Web Service的接口描述成“端口”,每個(gè)端口有一個(gè)或者多個(gè)“操作”,端口和操作的概念和Java的接口和方法類似。實(shí)際上,JAX-RPC定義了WSDL和Java RMI之間的映射關(guān)系,它產(chǎn)生來(lái)自端口的遠(yuǎn)端接口,并帶有響應(yīng)端口操作的方法。例如:一個(gè)WSDL文檔可能描述一個(gè)被稱作“BookPrice”、并帶有單個(gè)操作getBoolPrice的端口,下面就是BookPrice WSDL文檔的一些簡(jiǎn)單代碼:


<?xml version="1.0"?>

<definitions name="BookPrice"

targetNamespace="http://lucky.myrice.com/GetBookPrice"

xmlns:tns="http://lucky.myrice.com/GetBookPrice"

xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"

xmlns:xsd="http://www.w3.org/2001/XMLSchema"

xmlns="http://schemas.xmlsoap.org/wsdl/">

<!-- 描述參數(shù)和返回值的message元素 -->

<message name="IsbnMessage">

<part name="isbn" type="xsd:string" />

</message>

<message name="PriceMessage">

<part name="price" type="xsd:float" />

</message>

<!-- 描述Web Service抽象接口的portType元素 -->

<portType name="BookPrice">

<operation name="getBookPrice">

<input name="isbn" message="tns:IsbnMessage"/>

<output name="price" message="tns:PriceMessage"/>

</operation>

</portType>

<!-- 在這里進(jìn)行綁定 -->

<!-- service元素告訴我們Web Service的地址 -->

<service name="BookPriceService">

<port name="BookPrice" binding="tns:BookPrice_Binding">

<soap:address location="http://lucky.myrice.com/BookPrice" />

</port>

</service>

</definitions>


在部署的時(shí)候,JAX-RPC Stub生成工具會(huì)把WSDL端口轉(zhuǎn)換成遠(yuǎn)程接口和Stub,端口和服務(wù)Stub可能是下面的樣子:


public Interface BookPriceService extends javax.xml.rpc.Service{

public BookPrice getBookPrice( ) throws RemoteException;

}


public Interface BookPrice extends java.rmi.Remote {

public float getBookPrice(String isbn)

throws RemoteException;

}


這里只是一個(gè)簡(jiǎn)單的例子,這個(gè)服務(wù)只有一個(gè)端口,而實(shí)際上一個(gè)服務(wù)會(huì)有多個(gè)端口,每個(gè)端口有相應(yīng)的接口和Stub。一旦接口和Stub產(chǎn)生并被綁定到JNDI ENC之后,它們就可以在運(yùn)行期調(diào)用Web Service的“操作”了,在下面的無(wú)序會(huì)話Bean里,BookCatalog EJB利用JAX-RPC從.NET Web Webvices查找一本書的批發(fā)價(jià)格。


public class BookCatalog implements javax.ejb.SessionBean {

...

public float getWholeSalePrice(String isbn) {

try {


InitialContext jndiContext = new InitialContext ( );


BookPriceService service =

jndiContext.lookup("java:comp/env/service/BookPriceService");


BookPrice bookPrice_port = service.getBookPrice();


float price = bookPrice_port.getBookPrice( isbn );

return price;


catch(RemoteException re){

}catch(ServiceException se){

}catch(NamingException ne){

}

}

...

}


當(dāng)調(diào)用getBookPrice()方法時(shí),JAX-RPC Stub向.NET Web Service發(fā)送SOAP信息,Stub產(chǎn)生的SOAP信息可能會(huì)是下面的樣子:


<?xml version='1.0' ?>

<env:Envelope

xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:xyz='http://lucky.myrice.com/BookPrice"

encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">

<Body>

<xyz:getBookPrice>

<isbn xsi:type="string">1565928695

</xyz:getBookPrice>

</Body>

</env:Envelope>


.NET Erb Services處理SOAP信息,并把結(jié)果返回到Stub,Stub分析結(jié)果,最后向客戶端發(fā)送最終結(jié)果。

JAX-RPC Stub中的方法可以有參數(shù),參數(shù)類型可以是基本數(shù)據(jù)類型,如int,long等;基本包裝類型,如java.lang.Interger,java.lang.Long等;數(shù)組;Java標(biāo)準(zhǔn)類型,如String,Date等;也可以是自定義對(duì)象類型。自定義對(duì)象必須符合JAX-RPC規(guī)范的規(guī)則。

除了產(chǎn)生Stub外,JAX-RPC也支持動(dòng)態(tài)代理服務(wù),除了它的遠(yuǎn)程接口和Stub的實(shí)現(xiàn)是在運(yùn)行時(shí)動(dòng)態(tài)產(chǎn)生的之外,動(dòng)態(tài)代理服務(wù)的作用和Stub一樣。下面的例子就是JAX-RPC產(chǎn)生動(dòng)態(tài)Stub的:


public class BookCatalog implements javax.ejb.SessionBean {

...

public float getWholeSalePrice(String isbn) {

try {

InitialContext jndiContext = new InitialContext ( );

javax.xml.rpc.Service service =

jndiContext.lookup("java:comp/env/service/DynamicService");

BookPrice bookPrice_port = service.getPort(BookPrice.class);

float price = bookPrice_port.getBookPrice( isbn );

return price;

catch(RemoteException re){}

catch(ServiceException se){}

catch(NamingException ne){}

}

...

}


在運(yùn)行時(shí),getPort()方法自動(dòng)把BookPrice接口映射到WSDL文檔里定義的相應(yīng)端口,然后產(chǎn)生Stub實(shí)現(xiàn)接口的工作。

JAX-RPC還支持名為DII(Dynamic Invocation Interface)的動(dòng)態(tài)API,DII允許開發(fā)人員在運(yùn)行時(shí)調(diào)用SOAP方法。如果你使用過(guò)CORBA Dynamic Invocation Interface的話,那你對(duì)JAX-RPC DII一定很容易理解。JAX-RPC DII類似于Java的反射(Reflection),它允許你以方法的形式得到一個(gè)代表Web Service操作的對(duì)象的參考,調(diào)用那個(gè)方法,就無(wú)需再訪問(wèn)Service Factory或者再使用Stub和遠(yuǎn)端接口。下面的例子就是企業(yè)Bean訪問(wèn)BookPrice端口的getBookPrice()操作:


public class BookCatalog implements javax.ejb.SessionBean {

...

public float getWholeSalePrice(String isbn) {

try {

InitialContext jndiContext = new InitialContext ( );

javax.xml.rpc.Service service =

jndiContext.lookup("java:comp/env/service/DynamicService");

QName port = new QName("http://lucky.myrice.com/GetBookPrice ","BookPrice");

QName operation = new QName("http://lucky.myrice.com/GetBookPrice",

"getBookPrice");

Call callObject = service.createCall(port, operation);

Object [] args = new Object[1]; args[0] = isbn;

Float price = (Float) callObject.invoke( args );

return price.floatValue();

}

catch(JAXRPCException se){}

catch(NamingException ne){}

}

}

...

}


實(shí)際上,你可以在運(yùn)行期配置參數(shù)、類型、編碼等,你能用WSDL配置的所有信息都可以用DII動(dòng)態(tài)配置。

JAX-RPC另外還是一個(gè)稱為終端接口(Endpoint Interface)的新型組件,這個(gè)新接口允許我們把無(wú)序的會(huì)話Bean作為Web Service來(lái)實(shí)現(xiàn),這個(gè)終端接口簡(jiǎn)化了javax.rmi.Remote接口的實(shí)現(xiàn),并且遵守JAX-RPC規(guī)范中的規(guī)則。把一個(gè)無(wú)序的會(huì)話Bean作為Web Service來(lái)實(shí)現(xiàn)是非常簡(jiǎn)單的:只需定義Bean類和遠(yuǎn)端接口,然后使用開發(fā)商的提供的工具來(lái)實(shí)現(xiàn)。一旦建立了Web Service,它的方法就能夠被任何SOAP兼容的、來(lái)自任何語(yǔ)言和平臺(tái)的工具包來(lái)調(diào)用,比如:.NET,Perl,Apache Axis,C,C++等等。如下圖所示:

 

由于JAX-RPC僅僅是Java RMI的另外一種形式,因此,利用它訪問(wèn)企業(yè)Bean是很自然的,我們以前已經(jīng)利用RMI-IIOP和RMI訪問(wèn)過(guò)。利用JAX-RPC與EJB進(jìn)行通信意味著EJB可以當(dāng)作Web Service來(lái)使用,至少無(wú)序的Bean是可以的。EJB2.1允許我們利用JAX-RPC,但只能是應(yīng)用于無(wú)序的Bean,這主要是因?yàn)镾OAP是一種無(wú)序的消息協(xié)議,它沒(méi)有對(duì)象識(shí)別的概念,因此它不能應(yīng)用在有序的和實(shí)體的Bean中。

EJB2.1為無(wú)序的Bean定義了一個(gè)新的Web Service終端(EndPoint)接口,Web Service界的人使用“終端”來(lái)稱呼發(fā)送和接收SOAP信息的任何東西。在EJB中,終端就是一個(gè)無(wú)序的會(huì)話Bean,它可以通過(guò)SOAP來(lái)訪問(wèn),并且遵照J(rèn)AX-RPC規(guī)范中定義的從Java-to-WSDL到Java-to-SOAP的映射規(guī)則。使用JAX-RPC最為EJB終端的基礎(chǔ)是順理成章的,因?yàn)镴AX-RPC規(guī)范中定義了SOAP消息和Java方法調(diào)用以及從Java遠(yuǎn)程接口產(chǎn)生WSDL文檔的詳細(xì)規(guī)則。

不象EJB開發(fā)者已經(jīng)很熟悉的遠(yuǎn)端和本地接口,終端接口并沒(méi)有繼承EJB對(duì)象類型,如EJBObject或EJBLocalObject。相反,終端接口直接繼承了javax.ejb.Remote接口。例如:在上面的例子中的BookPrice的Web Service能夠很輕易實(shí)現(xiàn)為EJB中的終端。下面的代碼說(shuō)明了一個(gè)BookPrice的終端接口,和實(shí)現(xiàn)為Web Service的無(wú)序會(huì)話Bean的部分列表。


public interface BookPrice extends javax.rmi.Remote {

public String getBookPrice(String isbn) throws javax.rmi.RemoteException;

}


public class BookPriceWS implements BookPrice, javax.ejb.SessionBean {

public float getBookPrice(String isbn){

Connection con = null;

Statement stmt = null;

ResultSet rs;

try {

DataSource ds = jdniEnc.lookup("java:comp/env/jdbc/DataSource");

con = ds.getConneciton();

stmt = con.createStatement();

rs = stmt.executeQuery("SELECT wholesale FROM CATALOG WHERE isbn = '"

+isbn+"'");

if(rs.next()){

float price = rs.getFloat("wholesale");

return price;

}else{

return 0;

}

}

catch (SQLException se) {

file://處理異常

}

}

...

}


終端接口比遠(yuǎn)程和本地接口一個(gè)很明顯的好處就是它不會(huì)帶來(lái)象EJBObject或者EJBLocalObect無(wú)用方法等形式的額外負(fù)擔(dān),此外,終端接口沒(méi)有包括home接口,SOAP不支持按引用傳值。因此,你不能要求一個(gè)Web Services接口(home 接口)按引用傳遞到另外一個(gè)遠(yuǎn)端接口,更進(jìn)一步講,你不能創(chuàng)建或移除一個(gè)Web Service。

當(dāng)我們把一個(gè)無(wú)序會(huì)話 Bean開發(fā)成Web Service時(shí),首先定義一個(gè)終端接口,然后利用它產(chǎn)生JAX-RPC的客戶端Stub和WSDL文檔或者如果你產(chǎn)生JAX-RPC客戶端Stub,無(wú)需做任何改變,你可以把它包裝成J2EE客戶端JAR,利用它去訪問(wèn)無(wú)序會(huì)話Bean,利用SOAP做通訊協(xié)議。如果你從終端接口產(chǎn)生WSDL文檔,其它的SOAP工具包也能夠使用這個(gè)文檔去訪問(wèn)你的無(wú)序Bean。WSDL和SOAP是Web Service的基礎(chǔ),因此,為EJB Web Services發(fā)布WSDL可以實(shí)現(xiàn)與其它平臺(tái)的交互。

SAAJ

SAAJ(SOAP with Attachments API for Java)是一個(gè)基于API的SOAP工具包,它定義了SOAP Messages with Attachments (SwA)和SOAP用的MIME信息格式。Java開發(fā)人員能夠利用SAAJ來(lái)創(chuàng)建、讀取或者修改SOAP信息。這個(gè)API包含許多類和接口,用來(lái)定義SOAP元素(Envelope, Body, Header, Fault等),XML名稱空間,屬性,文字節(jié)點(diǎn)以及MIME附件。你可以使用SAAJ操作簡(jiǎn)單的、沒(méi)有附件的XML格式的SOAP信息,也可以操作更加復(fù)雜的、帶Mime附件的SOAP信息。SAAJ可以與JAX-RPC結(jié)合使用,但也可以單獨(dú)使用,它有自己的、通過(guò)HTTP1.1實(shí)現(xiàn)的請(qǐng)求/應(yīng)答方式的消息機(jī)制。

SAAJ是基于Abstract Factory模式的。SAAJ是類型的抽象集合,每一種類型的對(duì)象都是由SAAJ集合中另外的對(duì)象產(chǎn)生的。在Abstract Factory的SAAJ實(shí)現(xiàn)中,MessageFactory類是根,它負(fù)責(zé)創(chuàng)建自己的實(shí)例,反過(guò)來(lái)創(chuàng)建SOAPMessage,SOAPMessage包含SOAPPart,它代表SOAP文檔、0個(gè)和多個(gè)AttachmentPart(代表附件的對(duì)象,如GIF,PDF等)。SOAPPart包含SOAPEnvelope、SOAPBody、SOAPHeader和其它類型的對(duì)象。

要迅速了解SAAJ,我們先用XML格式建立一個(gè)簡(jiǎn)單的SOAP信息,如下所示:


<?xml version='1.0' ?>

<env:Envelope

xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'

xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'

xmlns:book='http://lucky.myrice.com/BookPrice'

encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>

<env:Body>

<book:getBookPrice>

<isbn xsi:type='string'>1565928695

</book:getBookPrice>

</env:Body>

</env:Envelope>


而下面是用SAAJ創(chuàng)建的例子:


import javax.xml.soap.*;


public class Example_1 {

public static void main(String [] args) throws SOAPException{


MessageFactory msgFactory = MessageFactory.newInstance();

SOAPMessage message = msgFactory.createMessage();

SOAPPart soap = message.getSOAPPart();

SOAPEnvelope envelope = soap.getEnvelope();

envelope.getHeader().detachNode();

SOAPBody body = envelope.getBody();

SOAPElement getBookPrice = body.addChildElement(

"getBookPrice","book",

"http://lucky.myrice.com/BookPrice");

getBookPrice.setEncodingStyle(SOAPConstants.URI_NS_SOAP_ENCODING);

SOAPElement isbn = getBookPrice.addChildElement("isbn");

isbn.addNamespaceDeclaration("xsi",

"http://www.w3.org/2001/XMLSchema-instance");

Name xsiType = envelope.createName("type","xsi",

"http://www.w3.org/2001/XMLSchema-instance");

isbn.addAttribute(xsiType,"string");

isbn.addTextNode("1565928695");

message.writeTo(System.out);

}

}


如果我們對(duì)比上面的例子,就會(huì)發(fā)現(xiàn)SAAJ定義了SwA消息格式的準(zhǔn)確結(jié)構(gòu),SOAP消息的屬性和SAAJ類型之間可以發(fā)現(xiàn)是一一對(duì)應(yīng)的關(guān)系:Envelope對(duì)應(yīng)SOAPEnvelope;Body對(duì)應(yīng)SOAPBody;getBoolPrice對(duì)應(yīng)SOAPBodyElement;isbn對(duì)應(yīng)SOAPElement(Text)等。

當(dāng)然,上面的例子是很簡(jiǎn)單的,它并沒(méi)有包含任何附件,SwA中的附件通常是二進(jìn)制或者是其它的非XML格式的文件,它通常被SOAP文檔引用。SAAJ靠JAF( Java Activation Framework)添加附件,并處理對(duì)象和數(shù)據(jù)流之間的相互轉(zhuǎn)換。下面的這段示例代碼利用SAAJ向SOAP附加一個(gè)PDF文件。


MessageFactory msgFactory = MessageFactory.newInstance();

SOAPMessage message = msgFactory.createMessage();

AttachmentPart pdfAttach = message.createAttachmentPart();

FileDataSource file = new FileDataSource("TestSAAJAttachment.pdf");

DataHandler pdfDH = new DataHandler(file);

pdfAttach.setDataHandler(pdfDH);


要成功處理附件,我們必須先理解JAF,JAF是處理MIME數(shù)據(jù)的極好框架,但它也有自己的局限性,大部分局限性與使用DataContentHandler類型有關(guān)。藏在JAF的局限性后面的細(xì)節(jié)問(wèn)題是很復(fù)雜的,但我們可以使用JAF DataSource類型來(lái)克服大部分的局限性,就象例子中的javax.activation.FileDataSource那樣。

SAAJ是一個(gè)用途廣泛的API,可以讓我們?cè)趲缀跞魏蔚膽?yīng)用中創(chuàng)建SwA消息,在某些情況下,我們可以與JAX-RPC一起在文字消息和SOAP消息中使用SAAJ,但也可以與其它的API如JavaMail,JMS,JAXM一起使用。如果Java應(yīng)用已經(jīng)創(chuàng)建了SwA消息,它仍可以使用SAAJ把這個(gè)消息轉(zhuǎn)換成二進(jìn)制流,然后與使用其它API的Web Services進(jìn)行交換信息。

JAXM 和 EJB

JAXM (Java API for XML Messaging)是和(Java Message Service)類似的SOAP消息API,就象JMS是一種通過(guò)面向消息的中間件來(lái)發(fā)送和接收消息的API一樣,JAXM是一種通過(guò)Web Service來(lái)發(fā)送和接收消息的API。

JAXM是面向文檔的,它把SOAP消息以XML格式的文檔來(lái)進(jìn)行傳送的。JAXM客戶端都是使用SAAJ(SOAP with Attachments API for Java)來(lái)裝配、接收和使用SOAP消息的,SAAJ模仿SOAP消息的實(shí)際XML結(jié)構(gòu),這種機(jī)制與JAX-RPC是有很大區(qū)別的,JAX-RPC使用方法調(diào)用的語(yǔ)法,把SOAP消息隱藏到了Java RMI代理的后面。使用JAX-RPC,你 所看到的是僅僅由方法、參數(shù)、返回值組成的遠(yuǎn)端接口,而使用JAXM,你直接處理SOAP協(xié)議。象JAX-RPC一樣,JAXM必須與SOAP兼容的Web Service交換SOAP信息。例如:一個(gè)企業(yè)Bean可能使用JAXM與用Perl寫的Web Service交換SOAP信息。EJB2.1開發(fā)者能夠以JAXM作為一種新的消息驅(qū)動(dòng)Bean的基礎(chǔ),我們稱它為基于JAXM的消息驅(qū)動(dòng)Bean(JAXM-MDB)。JAXM-MDB使用的是SOAP消息,但扮演的是Web Service的角色。JAXM-MDB能夠?qū)崿F(xiàn)單向的異步接口,就象基于JMS的消息驅(qū)動(dòng)的Bean,也可以實(shí)現(xiàn)請(qǐng)求/應(yīng)答式的同步接口。

JAX-RPC和JAXM都允許企業(yè)Bean訪問(wèn)不同平臺(tái)上的Web Service,也可以作為用無(wú)序和消息驅(qū)動(dòng)Bean建立的Web Service的基礎(chǔ)。但是,由于缺乏廠商的支持,JAXM的使用前景并不是很樂(lè)觀。

發(fā)布:2007-03-25 10:36    編輯:泛普軟件 · xiaona    [打印此頁(yè)]    [關(guān)閉]
相關(guān)文章:
上海OA系統(tǒng)
聯(lián)系方式

成都公司:成都市成華區(qū)建設(shè)南路160號(hào)1層9號(hào)

重慶公司:重慶市江北區(qū)紅旗河溝華創(chuàng)商務(wù)大廈18樓

咨詢:400-8352-114

加微信,免費(fèi)獲取試用系統(tǒng)

QQ在線咨詢