ejb2.1(enterprise javabeans 2.1)正式推荐版本已经出台,它产生的动力主要是enterprise javabeans对支持web service的需求,同时也是因为micr
osoft .net的发布,它对j2ee或者说对java技术来说已经构成了巨大威胁。在新版本的ejb2.1中,主要的变化主要集中在基于soap和wsdl的web service上。ejb已经成为一种新的web service平台。它对web service的支持主要体现在三个新的web service api上:分别是jax-rpc(java api for xml-rpc,它基本上是通过soap实现的java rmi,为rpc格式的soap消息提供远端接口)、saaj(soap api with attachments for java,它模仿soap消息的结构,同时也有功能有限的消息分发能力)和jaxm(java api for xml messaging,它类似于jms,提供发送和接收soap消息的消息架构),利用它们可以实现与其它类型的web service进行通讯,而且还允许无序的会话bean和消息驱动的bean来作为web service使用,使它们能够被任何与 soap1.1兼容的客户端所访问。例如:使用soap,我们就可以从其它平台web service来调用无序的会话bean的方法,象微软的.net,perl,apache axix和其他的语言和平台。ejb2.1中新的web service功能能够提供一种前所未有的跨平台互操作性,它主要是建立在两个崭新的j2ee soap工具包jax-rpc和jaxm。
web service代表了分布式计算的最新潮流,可能是自1995年java的出现和1998年xml出现以来最重要的技术了。其实,给web service下一个准确的定义是很难的,因为web service并不是任何特殊技术或者平台所特有的,web service是一种网络应用程序,以xml形式的文档,使用soap和wsdl进行信息交换。要更好地理解这句话的含义,你必须先理解soap和wsdl,下面是有关这方面的定义:
soap:简单对象访问协议(simple object access protocol),是在w3c的支持下,由microsoft,ibm和其他公司开发的,基于xml格式的一种协议,它是可伸缩和可扩展的,不象以前的dce rpc, corba iiop, java rmi-jrmp以及dcom,它已经被几乎所有的开发厂商所认可和接受。
wsdl:web服务描述语言(web service description language),也是在w3c的支持下,由microsoft,ibm和其他公司开发的,xml格式的语言,用来对web service进行描述,包括期望的消息格式类型、所使用的internet协议和web service的internet地址。
其实,web service代表了一种新的分布式对象技术,它和corba iiop和java rmi很相似,但也有许多差异,最大的差异应该就是真正的平台无关性。尽管java rmi和corba iiop都声称自己是平台无关的,但实际上,它们都需要它们自己的平台。要使用java rmi,你需要一个java虚拟机和java编程语言,对使用其它语言的开发者如visual basic或c++来说,java rmi并不是平台无关的。corba iiop也是有局限性的,iiop协议通常需要一个特定的架构如corba orb,也只有少数几个厂商支持corba。另一方面,web service着重描述信息交换的协议,而不是着重描述对这些协议的实现,换句话说,你可以用任何语言,在任何平台上,以任何你自己喜欢的方式来创建web service。
web service另外一个好处就是,不象其它的分布式对象体系,它建立在现有的技术架构的基础之上,因此大多说厂商很容易实现。soap和wsdl都是基于xml的,而xml已经被广泛支持,xml解析器在几乎每一种开发语言中都有,因此,处理soap消息和wsdl文档的基础已经存在了。此外,web service消息通常是通过tcp/ip进行交换的,也已经被几乎所有的平台和语言所支持。
jax-rpc和ejb
jax-rpc(java api for xml-rpc)实质上就是通过soap访问的java rmi。它和“本地的”java rmi (java rmi-jrmp)和java rmi-iiop很象,但是它是以soap作为通讯协议。要实现jax-rpc,最低要求是必须对通过http访问的soap支持rpc编码,但是,我们仍然可以提供对其他编码方式、消息格式和internet协议的支持。jax-rpc能够被用来从会话、实体和消息驱动的bean来调用web service的操作。jax-rpc能够用来访问其它平台的web service。例如:一个无序的会话bean可能会使用jax-rpc来调用.net web service的方法。如下图所示:
每个ejb开发商都会提供自己对jax-rpc的实现,但它们之间的差别是很小的,主要是因为所有的实现都必须遵照jax-rpc规范,jax-rpc能够当作客户端api来访问其它的web service,但是,它同时也是一个被称作“endpoint接口”的新型企业bean接口。当jax-rpc当作客户端api的时候,会话、实体或者消息驱动的bean能够使用它与其它平台的web service交换消息。jax-rpc定义了三种编程模型:generated stub、dynamic proxy和dii(dynamic invocation interface),我们在ejb环境中常用的generated stub模型。
如果使用jax-rpc去访问web service,那么,这个web service必须发行一个wsdl文档,ejb开发商提供的jax-rpc工具包产生java rmi接口和实现wsdl文档所描述的web service操作的stub,一旦stub和接口创建出来之后,我们就可以把它们与企业bean的jndi enc(environment naming context)进行绑定,然后与 web service进行通信。
wsdl把访问web service的接口描述成“端口”,每个端口有一个或者多个“操作”,端口和操作的概念和java的接口和方法类似。实际上,jax-rpc定义了wsdl和java rmi之间的映射关系,它产生来自端口的远端接口,并带有响应端口操作的方法。例如:一个wsdl文档可能描述一个被称作“bookprice”、并带有单个操作getboolprice的端口,下面就是bookprice wsdl文档的一些简单代码:
<?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/">
<!-- 描述参数和返回值的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>
<!-- 在这里进行绑定 -->
<!-- service元素告诉我们web service的地址 -->
<service name="bookpriceservice">
<port name="bookprice" binding="tns:bookprice_binding">
<soap:address location="http://lucky.myrice.com/bookprice" />
</port>
</service>
</definitions>
在部署的时候,jax-rpc stub生成工具会把wsdl端口转换成远程接口和stub,端口和服务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;
}
这里只是一个简单的例子,这个服务只有一个端口,而实际上一个服务会有多个端口,每个端口有相应的接口和stub。一旦接口和stub产生并被绑定到jndi enc之后,它们就可以在运行期调用web service的“操作”了,在下面的无序会话bean里,bookcatalog ejb利用jax-rpc从.net web webvices查找一本书的批发价格。
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){
}
}...
}
当调用getbookprice()方法时,jax-rpc stub向.net web service发送soap信息,stub产生的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: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信息,并把结果返回到stub,stub分析结果,最后向客户端发送最终结果。
jax-rpc stub中的方法可以有参数,参数类型可以是基本数据类型,如int,long等;基本包装类型,如java.lang.interger,java.lang.long等;数组;java标准类型,如string,date等;也可以是自定义对象类型。自定义对象必须符合jax-rpc规范的规则。
除了产生stub外,jax-rpc也支持动态代理服务,除了它的远程接口和stub的实现是在运行时动态产生的之外,动态代理服务的作用和stub一样。下面的例子就是jax-rpc产生动态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){}
}
...
}
在运行时,getport()方法自动把bookprice接口映射到wsdl文档里定义的相应端口,然后产生stub实现接口的工作。
jax-rpc还支持名为dii(dynamic invocation interface)的动态api,dii允许开发人员在运行时调用soap方法。如果你使用过corba dynamic invocation interface的话,那你对jax-rpc dii一定很容易理解。jax-rpc dii类似于java的反射(reflection),它允许你以方法的形式得到一个代表web service操作的对象的参考,调用那个方法,就无需再访问service factory或者再使用stub和远端接口。下面的例子就是企业bean访问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){}
}
}
...
-
关于我们
公司介绍 最新动态 联系我们 -
产品与服务
域名注册 jsp空间 php空间 -
常见问题
空间操作手册 网站备案相关 退款相关问题 -
技术支持
技术 QQ :178966803 联系电话:13616026886 联系邮箱:fjjsp@vip.163.com
扫描关注微信公众号
闽公网安备 35060202000074号