webservice使用EJB.docx
- 文档编号:23492922
- 上传时间:2023-05-17
- 格式:DOCX
- 页数:14
- 大小:38.48KB
webservice使用EJB.docx
《webservice使用EJB.docx》由会员分享,可在线阅读,更多相关《webservice使用EJB.docx(14页珍藏版)》请在冰豆网上搜索。
webservice使用EJB
EJB2.1(EnterpriseJavaBeans2.1)正式推荐版本已经出台,它产生的动力主要是EnterpriseJavaBeans对支持WebService的需求,同时也是因为Microsoft.NET的发布,它对J2EE或者说对Java技术来说已经构成了巨大威胁。
在新版本的EJB2.1中,主要的变化主要集中在基于SOAP和WSDL的WebService上。
EJB已经成为一种新的WebService平台。
它对WebService的支持主要体现在三个新的WebServiceAPI上:
分别是JAX-RPC(JavaAPIforXML-RPC,它基本上是通过SOAP实现的JavaRMI,为RPC格式的SOAP消息提供远端接口)、SAAJ(SOAPAPIwithAttachmentsforJava,它模仿SOAP消息的结构,同时也有功能有限的消息分发能力)和JAXM(JavaAPIforXMLMessaging,它类似于JMS,提供发送和接收SOAP消息的消息架构),利用它们可以实现与其它类型的WebService进行通讯,而且还允许无序的会话Bean和消息驱动的Bean来作为WebService使用,使它们能够被任何与SOAP1.1兼容的客户端所访问。
例如:
使用SOAP,我们就可以从其它平台WebService来调用无序的会话Bean的方法,象微软的.NET,Perl,ApacheAxix和其他的语言和平台。
EJB2.1中新的WebService功能能够提供一种前所未有的跨平台互操作性,它主要是建立在两个崭新的J2EESOAP工具包JAX-RPC和JAXM。
WebService代表了分布式计算的最新潮流,可能是自1995年Java的出现和1998年XML出现以来最重要的技术了。
其实,给WebService下一个准确的定义是很难的,因为WebService并不是任何特殊技术或者平台所特有的,WebService是一种网络应用程序,以XML形式的文档,使用SOAP和WSDL进行信息交换。
要更好地理解这句话的含义,你必须先理解SOAP和WSDL,下面是有关这方面的定义:
SOAP:
简单对象访问协议(SimpleObjectAccessProtocol),是在W3C的支持下,由Microsoft,IBM和其他公司开发的,基于XML格式的一种协议,它是可伸缩和可扩展的,不象以前的DCERPC,CORBAIIOP,JavaRMI-JRMP以及DCOM,它已经被几乎所有的开发厂商所认可和接受。
WSDL:
Web服务描述语言(WebServiceDescriptionLanguage),也是在W3C的支持下,由Microsoft,IBM和其他公司开发的,XML格式的语言,用来对WebService进行描述,包括期望的消息格式类型、所使用的Internet协议和WebService的Internet地址。
其实,WebService代表了一种新的分布式对象技术,它和CORBAIIOP和JavaRMI很相似,但也有许多差异,最大的差异应该就是真正的平台无关性。
尽管JavaRMI和CORBAIIOP都声称自己是平台无关的,但实际上,它们都需要它们自己的平台。
要使用JavaRMI,你需要一个Java虚拟机和Java编程语言,对使用其它语言的开发者如VisualBasic或C++来说,JavaRMI并不是平台无关的。
CORBAIIOP也是有局限性的,IIOP协议通常需要一个特定的架构如CORBAORB,也只有少数几个厂商支持CORBA。
另一方面,WebService着重描述信息交换的协议,而不是着重描述对这些协议的实现,换句话说,你可以用任何语言,在任何平台上,以任何你自己喜欢的方式来创建WebService。
WebService另外一个好处就是,不象其它的分布式对象体系,它建立在现有的技术架构的基础之上,因此大多说厂商很容易实现。
SOAP和WSDL都是基于XML的,而XML已经被广泛支持,XML解析器在几乎每一种开发语言中都有,因此,处理SOAP消息和WSDL文档的基础已经存在了。
此外,WebService消息通常是通过TCP/IP进行交换的,也已经被几乎所有的平台和语言所支持。
JAX-RPC和EJBJAX-RPC(JavaAPIforXML-RPC)实质上就是通过SOAP访问的JavaRMI。
它和“本地的”JavaRMI(JavaRMI-JRMP)和JavaRMI-IIOP很象,但是它是以SOAP作为通讯协议。
要实现JAX-RPC,最低要求是必须对通过HTTP访问的SOAP支持RPC编码,但是,我们仍然可以提供对其他编码方式、消息格式和Internet协议的支持。
JAX-RPC能够被用来从会话、实体和消息驱动的Bean来调用WebService的操作。
JAX-RPC能够用来访问其它平台的WebService。
例如:
一个无序的会话Bean可能会使用JAX-RPC来调用.NETWebService的方法。
如下图所示:
每个EJB开发商都会提供自己对JAX-RPC的实现,但它们之间的差别是很小的,主要是因为所有的实现都必须遵照JAX-RPC规范,JAX-RPC能够当作客户端API来访问其它的WebService,但是,它同时也是一个被称作“EndPoint接口”的新型企业Bean接口。
当JAX-RPC当作客户端API的时候,会话、实体或者消息驱动的Bean能够使用它与其它平台的WebService交换消息。
JAX-RPC定义了三种编程模型:
GeneratedStub、DynamicProxy和DII(DynamicInvocationInterface),我们在EJB环境中常用的GeneratedStub模型。
如果使用JAX-RPC去访问WebService,那么,这个WebService必须发行一个WSDL文档,EJB开发商提供的JAX-RPC工具包产生JavaRMI接口和实现WSDL文档所描述的WebService操作的Stub,一旦Stub和接口创建出来之后,我们就可以把它们与企业Bean的JNDIENC(EnvironmentNamingContext)进行绑定,然后与WebService进行通信。
WSDL把访问WebService的接口描述成“端口”,每个端口有一个或者多个“操作”,端口和操作的概念和Java的接口和方法类似。
实际上,JAX-RPC定义了WSDL和JavaRMI之间的映射关系,它产生来自端口的远端接口,并带有响应端口操作的方法。
例如:
一个WSDL文档可能描述一个被称作“BookPrice”、并带有单个操作getBoolPrice的端口,下面就是BookPriceWSDL文档的一些简单代码:
xmlversion="1.0"?
>
targetNamespace=" xmlns: tns=" xmlns: soap="http: //schemas.xmlsoap.org/wsdl/soap/" xmlns: xsd="http: //www.w3.org/2001/XMLSchema" xmlns="http: //schemas.xmlsoap.org/wsdl/"> --描述参数和返回值的message元素--> string"/> float"/> --描述WebService抽象接口的portType元素--> IsbnMessage"/> PriceMessage"/> --在这里进行绑定--> --service元素告诉我们WebService的地址--> BookPrice_Binding"> addresslocation="/> 在部署的时候,JAX-RPCStub生成工具会把WSDL端口转换成远程接口和Stub,端口和服务Stub可能是下面的样子: publicInterfaceBookPriceServiceextendsjavax.xml.rpc.Service{ publicBookPricegetBookPrice()throwsRemoteException; } publicInterfaceBookPriceextendsjava.rmi.Remote{ publicfloatgetBookPrice(Stringisbn) throwsRemoteException; } 这里只是一个简单的例子,这个服务只有一个端口,而实际上一个服务会有多个端口,每个端口有相应的接口和Stub。 一旦接口和Stub产生并被绑定到JNDIENC之后,它们就可以在运行期调用WebService的“操作”了,在下面的无序会话Bean里,BookCatalogEJB利用JAX-RPC从.NETWebWebvices查找一本书的批发价格。 publicclassBookCatalogimplementsjavax.ejb.SessionBean{ ... publicfloatgetWholeSalePrice(Stringisbn){ try{ InitialContextjndiContext=newInitialContext(); BookPriceServiceservice= jndiContext.lookup("java: comp/env/service/BookPriceService"); BookPricebookPrice_port=service.getBookPrice(); floatprice=bookPrice_port.getBookPrice(isbn); returnprice; catch(RemoteExceptionre){ }catch(ServiceExceptionse){ }catch(NamingExceptionne){ } } ... } 当调用getBookPrice()方法时,JAX-RPCStub向.NETWebService发送SOAP信息,Stub产生的SOAP信息可能会是下面的样子: xmlversion='1.0'? > Envelope xmlns: env="http: //schemas.xmlsoap.org/soap/envelope/" xmlns: xsi="http: //www.w3.org/2001/XMLSchema-instance" xmlns: xyz=' encodingStyle="http: //schemas.xmlsoap.org/soap/encoding/"> getBookPrice> type="string">1565928695 getBookPrice> Envelope> .NETErbServices处理SOAP信息,并把结果返回到Stub,Stub分析结果,最后向客户端发送最终结果。 JAX-RPCStub中的方法可以有参数,参数类型可以是基本数据类型,如int,long等;基本包装类型,如java.lang.Interger,java.lang.Long等;数组;Java标准类型,如String,Date等;也可以是自定义对象类型。 自定义对象必须符合JAX-RPC规范的规则。 除了产生Stub外,JAX-RPC也支持动态代理服务,除了它的远程接口和Stub的实现是在运行时动态产生的之外,动态代理服务的作用和Stub一样。 下面的例子就是JAX-RPC产生动态Stub的: publicclassBookCatalogimplementsjavax.ejb.SessionBean{ ... publicfloatgetWholeSalePrice(Stringisbn){ try{ InitialContextjndiContext=newInitialContext(); javax.xml.rpc.Serviceservice= jndiContext.lookup("java: comp/env/service/DynamicService"); BookPricebookPrice_port=service.getPort(BookPrice.class); floatprice=bookPrice_port.getBookPrice(isbn); returnprice; catch(RemoteExceptionre){} catch(ServiceExceptionse){} catch(NamingExceptionne){} } ... } 在运行时,getPort()方法自动把BookPrice接口映射到WSDL文档里定义的相应端口,然后产生Stub实现接口的工作。 JAX-RPC还支持名为DII(DynamicInvocationInterface)的动态API,DII允许开发人员在运行时调用SOAP方法。 如果你使用过CORBADynamicInvocationInterface的话,那你对JAX-RPCDII一定很容易理解。 JAX-RPCDII类似于Java的反射(Reflection),它允许你以方法的形式得到一个代表WebService操作的对象的参考,调用那个方法,就无需再访问ServiceFactory或者再使用Stub和远端接口。 下面的例子就是企业Bean访问BookPrice端口的getBookPrice()操作: publicclassBookCatalogimplementsjavax.ejb.SessionBean{ ... publicfloatgetWholeSalePrice(Stringisbn){ try{ InitialContextjndiContext=newInitialContext(); javax.xml.rpc.Serviceservice= jndiContext.lookup("java: comp/env/service/DynamicService"); QNameport=newQName("","BookPrice"); QNameoperation=newQName(" "getBookPrice"); CallcallObject=service.createCall(port,operation); Object[]args=newObject[1];args[0]=isbn; Floatprice=(Float)callObject.invoke(args); returnprice.floatValue(); } catch(JAXRPCExceptionse){} catch(NamingExceptionne){} } } ... } 实际上,你可以在运行期配置参数、类型、编码等,你能用WSDL配置的所有信息都可以用DII动态配置。 JAX-RPC另外还是一个称为终端接口(EndpointInterface)的新型组件,这个新接口允许我们把无序的会话Bean作为WebService来实现,这个终端接口简化了javax.rmi.Remote接口的实现,并且遵守JAX-RPC规范中的规则。 把一个无序的会话Bean作为WebService来实现是非常简单的: 只需定义Bean类和远端接口,然后使用开发商的提供的工具来实现。 一旦建立了WebService,它的方法就能够被任何SOAP兼容的、来自任何语言和平台的工具包来调用,比如: .NET,Perl,ApacheAxis,C,C++等等。 如下图所示: 由于JAX-RPC仅仅是JavaRMI的另外一种形式,因此,利用它访问企业Bean是很自然的,我们以前已经利用RMI-IIOP和RMI访问过。 利用JAX-RPC与EJB进行通信意味着EJB可以当作WebService来使用,至少无序的Bean是可以的。 EJB2.1允许我们利用JAX-RPC,但只能是应用于无序的Bean,这主要是因为SOAP是一种无序的消息协议,它没有对象识别的概念,因此它不能应用在有序的和实体的Bean中。 EJB2.1为无序的Bean定义了一个新的WebService终端(EndPoint)接口,WebService界的人使用“终端”来称呼发送和接收SOAP信息的任何东西。 在EJB中,终端就是一个无序的会话Bean,它可以通过SOAP来访问,并且遵照JAX-RPC规范中定义的从Java-to-WSDL到Java-to-SOAP的映射规则。 使用JAX-RPC最为EJB终端的基础是顺理成章的,因为JAX-RPC规范中定义了SOAP消息和Java方法调用以及从Java远程接口产生WSDL文档的详细规则。 不象EJB开发者已经很熟悉的远端和本地接口,终端接口并没有继承EJB对象类型,如EJBObject或EJBLocalObject。 相反,终端接口直接继承了javax.ejb.Remote接口。 例如: 在上面的例子中的BookPrice的WebService能够很轻易实现为EJB中的终端。 下面的代码说明了一个BookPrice的终端接口,和实现为WebService的无序会话Bean的部分列表。 publicinterfaceBookPriceextendsjavax.rmi.Remote{ publicStringgetBookPrice(Stringisbn)throwsjavax.rmi.RemoteException; } publicclassBookPriceWSimplementsBookPrice,javax.ejb.SessionBean{ publicfloatgetBookPrice(Stringisbn){ Connectioncon=null; Statementstmt=null; ResultSetrs; try{ DataSourceds=jdniEnc.lookup("java: comp/env/jdbc/DataSource"); con=ds.getConneciton(); stmt=con.createStatement(); rs=stmt.executeQuery("SELECTwholesaleFROMCATALOGWHEREisbn=\'" +isbn+"\'"); if(rs.next()){ floatprice=rs.getFloat("wholesale"); returnprice; }else{ return0; } } catch(SQLExceptionse){ //处理异常 } } ... } 终端接口比远程和本地接口一个很明显的好处就是它不会带来象EJBObject或者EJBLocalObect无用方法等形式的额外负担,此外,终端接口没有包括home接口,SOAP不支持按引用传值。 因此,你不能要求一个WebServices接口(home接口)按引用传递到另外一个远端接口,更进一步讲,你不能创建或移除一个WebService。 当我们把一个无序会话Bean开发成WebService时,首先定义一个终端接口,然后利用它产生JAX-RPC的客户端Stub和WSDL文档或者如果你产生JAX-RPC客户端Stub,无需做任何改变,你可以把它包装成J2EE客户端JAR,利用它去访问无序会话Bean,利用SOAP做通讯协议。 如果你从终端接口产生WSDL文档,其它的SOAP工具包也能够使用这个文档去访问你的无序Bean。 WSDL和SOAP是WebService的基础,因此,为EJBWebServices发布WSDL可以实现与其它平台的交互。 SAAJSAAJ(SOAPwithAttachmentsAPIforJava)是一个基于API的SOAP工具包,它定义了SOAPMessageswithAttachments(SwA)和SOAP用的MIME信息格式。 Java开发人员能够利用SAAJ来创建、读取或者修改SOAP信息。 这个API包含许多类和接口,用来定义SOAP元素(Envelope,Body,Header,Fault等),XML名称空间,属性,文字节点以及MIME附件。 你可以使用SAAJ操作简单的、没有附件的XML格式的SOAP信息,也可以操作更加复杂的、带Mime附件的SOAP信息。 SAAJ可以与JAX-RPC结合使用,但也可以单独使用,它有自己的、通过HTTP1.1实现的请求/应答方式的消息机制。 SAAJ是基于AbstractFactory模式的。 SAAJ是类型的抽象集合,每一种类型的对象都是由SAAJ集合中另外的对象产生的。 在AbstractFactory的SAAJ实现中,MessageFactory类是根,它负责创建自己的实例,反过来创建SOAPMessage,SOAPMessage包含SOAPPart,它代表SOAP文档、0个和多个AttachmentPart(代表附件的对象,如GIF,PDF等)。 SOAPPart包含SOAPEnvelope、SOAPBody、SOAPHeader和其它类
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- webservice 使用 EJB