您的位置:首页 > 其它

XFire:开发Web服务的简单方式

2007-09-11 06:53 615 查看

XFire:开发Web服务的简单方式


Web服务是我们能够构建分布式系统,在这样的分布式系统中,网络上的应用组件能以一种平台无关、语言无关且实现独立的方式来访问。应用是如何开发的、使用了什么语言或者要运行在什么样的操作系统平台上都无所谓。如果它能用作Web服务,并被设计以解决交互问题,不管你的应用能够以何种语言或平台开发,都能使用它的服务。这就是Web服务的主要概念。
为能够平台无关和实现独立地访问Web服务,软件业赞同将一部分技术作为标准。如:
l XML——默认的数据格式,被用于Web服务环境中的所有层次。
l SOAP——默认的包装和交换消息的协议。第一次介绍时,它是Simple Object Access Protocol的首字母缩写。现在,人们认识到以前对SOAP的理解是有误的:SOAP并不只是为了访问对象。另外,它也并不简单。
l WSDL——描述Web服务的语言。尽管基于XML并能为人所理解,WSDL主要是为机器使用的,使客户程序能读并理解它。
下图展示了所有的技术是如何在一个环境中工作的。



这里,Provider是提供服务的应用组件,Requester是使用服务的客户程序。很多其他的技术可能会参加到交互中,但是上图展示的是Web服务环境中必不可少的核心组件。
XFire是一个免费的、开源的SOAP框架,它不只使你很简单直观地实现上述环境,还能提供很多在Web服务规范中定义的高级特性,但在大部分商业或开源工具中还不可得。
如果你的Web应用有一个Java类,而你希望把它的方法发布为Web服务,使用XFire,你可以不写一行多余的Java代码就能实现。只需写发布描述就可以获得一个Web服务。
一个简单的Java
这是一个银行应用的例子,运行在Apache Tomcat5.5.7和J2SE1.4.2_07环境。这个例子很简单,只做一件事——将资金从一个账户转入另一个账户。一个清晰的Java类BankingSerivce实现了这一工作,它包含一个名为transferFunds()的方法。它需要四个输入参数:
1.String fromAccount
2.String toAccount
3.double amount
4.String currency
下面是代码:
package com.mybank.xfire.example;



import java.text.NumberFormat;

import java.text.DecimalFormat;



/** XFire WebServices sample implementation class.

*/

public class BankingService implements IBankingService {

//Default constructor.

public BankingService(){

}

/** Transfers fund from one account to another.

*/

public String transferFunds(

String fromAccount, String toAccount, double amount, String currency){

String statusMessage = "";

//Call business objects and other components to get the job done.

//Then create a status message and return.

try {

NumberFormat formatter = new DecimalFormat("###,###,###,###.00");

statusMessage = "COMPLETED: " + currency + " " + formatter.format(amount)+

" was successfully transferred from A/C# " + fromAccount + " to A/C# " + toAccount;

} catch (Exception e){

statusMessage = "BankingService.transferFunds(): EXCEPTION: " + e.toString();

}

return statusMessage;

}

}

由于使用接口是一个很好的习惯,这里的Java类也实现了一个名为IBankingService的接口。该接口的代码如下:
package com.mybank.xfire.example;

public interface IBankingService {

public String transferFunds(

String fromAccount, String toAccount, double amount, String currency);


}

在实际的实现中,这样的方法可能包含所有类型的复杂调用、查询和处理操作。但是,这里的例子很小,因此,可以集中在我们的目标上:将方法发布为一个Web服务。

可以看到,上述代码就是一个简单的Java类。这里不需要加入任何的内容。将其发布为Web服务是所有要做的工作将在发布描述中完成。

Web应用的发布描述(Deployment description
在Java中,Web应用通常至少使用一个发布描述来配置,即web.xml。XFire本身是一个基于servlet的应用。因此,必须添加对这个文件的引用。之后,我们需要配置生成的Web服务。我们将使用一个新的名为services.xml来配置服务。

web.xml

首先,完成web.xml。我们必须添加下面的XFire servlet相关的实体:

<servlet>

<servlet-name>XFireServlet</servlet-name>

<display-name>XFire Servlet</display-name>

<servlet-class>org.codehaus.xfire.transport.http.XfireConfigurableServlet

 </servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>XFireServlet</servlet-name>

<url-pattern>/servlet/XFireServlet/*</url-pattern>

</servlet-mapping>


<servlet-mapping>

<servlet-name>XFireServlet</servlet-name>

<url-pattern>/services/*</url-pattern>

</servlet-mapping>

services.xml

目前,我们需要说明我们的Web服务的构成。这是在一个名为services.xml的文件中完成的,该文件被放置在META-INF/xfire目录下。这个完整的目录被放置在WEB-INF/classes文件夹下,这是Web应用程序的标准路径。下面是services.xml中基本的配置实体:

<beans xmlns="http://xfire.codehaus.org/config/1.0">

<service>

<name>Banking</name>

<namespace>mybank</namespace>

<serviceClass>com.mybank.xfire.example.IBankingService</serviceClass>

<implementationClass>com.mybank.xfire.example.BankingService

</implementationClass>

</service>

</beans>

对Web服务的定义包含在一个<service>元素中,它包含一些子元素。第一个子元素是<name>,它可以是你提供的任何合法的XML名字。这将由客户程序和其他组件使用以定位你的服务。例如,当一个服务发布之后,你将使用这个名字在浏览器中查看WSDL。

下一个子元素是<namespace>。任何合法的XML名字都是可以的。<namespace>将被用于唯一标识服务的不同参数。

<serviceClass>
元素包含Java类的名字,该名字规范方法的签名。在我们的例子中,它是接口IBankingService。如果你的Java类没有实现任何接口,就需要将类名放在这里。在你的Java类或接口中可能有一些方法。但作为Web服务,只有一个入口需要发布出去。

<implentationClass>
包含具有方法实现的Java类名。这是一个可选的元素。如果前面的元素<serviceClass>包含一个接口,相关的实现类必须在这里命名。

这就是完整地对我们的Web服务进行的配置。

XFire
和其他库

现在进入最后一步,获得所有必需的库文件。在XFire的网站上,下载xfire-distribution-1.0.zip,解压到一个本地文件夹。拷贝下面的jar文件到WEB-INF/lib目录下:

l 
activation-1.0.2.jar

l 
commons-codec-1.3.jar

l 
commons-httpclient-3.0.jar

l 
commons-logging-1.0.4.jar

l 
jaxen-1.1-beta-8.jar

l 
jdom-1.0.jar

l 
log4j-1.2.x.jar

l 
mail-1.3.3_01.jar

l 
spring-1.2.x.jar

l 
stax-api-1.0.jar

l 
wsdl4j-1.5.2.jar

l 
wstx-asl-2.9.jar

l 
xbean-2.1.0.jar

l 
xbean-spring-2.2.jar

l 
xfire-all-1.0.jar

l 
XmlSchema-1.0.jar

现在,可以发布和启动应用了。为了发布这个例子应用,拷贝websvc.war到Apache Tomcat环境下的webapps目录,并等几秒钟。它将自动启动。应用的全部源代码也都包含在这个war文件中。现在我们的程序已经是一个Web服务了。

我们如何知道Web服务在工作?
为了查看Web服务是否正在工作,我们必须测试。首先,测试WSDL是否可用。在浏览器中输入URL。由于我们应用的war文件是websvc.war,并且在service.xml中给出的服务名是Banking,WSDL的URL应该是:http://localhost:8080/websvc/services/Banking?wsdl

注意:URL的第一部分,即http://localhost:8080可能根据应用服务器的不同而不同。当输入URL,将能看到一个XML文档,它的根元素是<wsdl:definitions>。这个文档被称为服务的WSDL。如果能看到它,这是你的应用作为Web服务的第一个验证。


但是这个测试并不完全。在能看到WSDL的地方可能会出现状况,因此,客户端可能无法访问服务。所以,为了验证服务是否启动,我们必须用客户端程序作一个实际的测试,即实际调用服务。


开发客户端
可以用SOAP工具开发客户端,如.net或Apache Axis,有很多不同的方式:使用WSDL生成的存根,使用动态代理,等。
在我们的例子中,我们使用在一个名为WsClient.java的简单servlet中的动态代理。为了保证尽量少的编码,所有屏幕构建元素被放置在doGet()方法中。对Web服务实际的调用在callWebService()方法中,它很简单。

/* Call the Web service */

public String callWebService(

String fromAccount, String toAccount, double amount, String currency) 

throws MalformedURLException, Exception {


//Create a metadata of the service

Service serviceModel = new ObjectServiceFactory().create(IBankingService.class);

log.debug("callSoapServiceLocal(): got service model." );


//Create a proxy for the deployed service

XFire xfire = XFireFactory.newInstance().getXFire();

XFireProxyFactory factory = new XFireProxyFactory(xfire);


String serviceUrl = "http://localhost:8080/websvc/services/Banking";


IBankingService client = null;

try {

client = (IBankingService) factory.create(serviceModel, serviceUrl);

} catch (MalformedURLException e) {

log.error("WsClient.callWebService(): EXCEPTION: " + e.toString());

}


//Invoke the service

String serviceResponse = "";

try { 

serviceResponse = client.transferFunds(fromAccount, toAccount, amount, currency);

} catch (Exception e){

log.error("WsClient.callWebService(): EXCEPTION: " + e.toString()); 

serviceResponse = e.toString();

}

log.debug("WsClient.callWebService(): status=" + serviceResponse);





[code]//Return the response

return serviceResponse;

} 



首先,我们创建一个服务模型,该模型包含服务规范,即服务的元数据
。使用XFire的ObjectServiceFactory从接口IBankingService创建这个模型。

下一步是获得XFire的代理工厂对象
,它包含运行时代码,这一步很简单、直观。在这一步中应用没有制定任何东西。从proxyFactory开始,使用服务模型和服务端点(endpoint)URL(用于获得WSDL),我们获得一个Web服务的本地代理。

这个代理是一个实际的客户端。现在,我们可以激活它的transferFunds()方法来获得我们需要的服务。

一旦例子应用被发布并启动,尝试servlet URL:http://localhost:8080/websvc/ws

Servlet
使用默认的参数来调用Web服务并展示收到的响应。最后两行如下:

Response Received

COMPLETED: CDN$ 500.00 was successfully transferred from A/C# 11111-01234 to A/C# 99999-05678

现在,可以肯定Web服务已经启动并正在运行。

为了使用不同的输入参数,也可以使用一个完整的URL,如:http://localhost:8080/websvc/ws?from=11-2345&to=77-9876&amt=250.00&cur=EUR



基本Web服务开发清单
这个清单总结了将一个Java方法发布为Web服务需要的步骤:

1. 
检查Java类的方法和默认构造函数是public的

2. 
向web.xml添加XFire servlet相关的实体

3. 
创建services.xml并将其放置到WEB-INF/classes/META-INF/xfire目录

4. 
将XFire和其他第三方库添加到Web应用的WEB-INF/lib目录。

这就是所有需要完成的工作。

XFire的其它高级特性
XFire
可能很容易使用,但是在特性和功能方面,它是占据领先地位的。它的高级特性有:

l 
支持简单Java对象(POJOs-plain-old Java objects)、XMLBeans、XML绑定的Java框架(JAXB-Java Architecture for XML Binding)、Castor等的本地数据绑定。数据绑定规定XML请求如何到达Web服务,以及输出的XML响应如何映射到Java对象。

l 
使用XML的流API(StAX-Streaming API for XML)处理XML文档。与给予DOM(Document Object Model)树的方法和XML事件驱动的简单API方法相反,StAX使用基于拉(pull-based)的机制,使它更快且节省内存。

l 
支持各种传输协议,如HTTP、Java消息服务(Java Message Service)和in-JVM传输。

l 
嵌入能力,这是XFire的一个核心吸引力。你能将这个SOAP引擎嵌入到应用中,并完全地隐藏所有XFire规定的引用,好像所有的配置都是程序驱动的。

l 
丰富的API,这使它具有高度的可定制能力,并允许开发者解析不同阶段的请求,并按照需要处理它们。

l 
与最新标准如SOAP1.1(没有实现远程过程调用,或RPC)和1.2、WSDL1.1、Web服务交互组织的基本规范1.0(Web Service Interoperability Organization
s Basic Profile 1.0
)、Web服务寻址和Web服务安全等一致。

最重要地,XFire属于一个新生的Web服务引擎。不只是一个市场概念,“新生代”具有一些特性。Apache Axis是Java编写的第一批Web服务引擎之一,并已经成为所有之后出现的工具的基准。在过去的几年中,Axis和这些工具已经在很多生产环境中得到了领域特殊。从性能和效率看,面向文档的消息形式是今后的方向。但是,Apache Axis和大多数其它Web服务引擎在设计上都是面向RPC的(尽管它们支持文档方式)。业界目前正在开发新一代的SOAP引擎,它们在设计上是面向文档的。Apache已经公布结束对老版本Axis引擎的开发,目前正在开发Axis2,当前版本0.95。XFire已经在2006年2月份创建了它的第一个产品版本(1.0)。它的下一个版本(1.1)在几周后就出现了。

性能
Web
服务需要大量的资源,但是在性能方面这是不赞成的。XFire打破了这个趋势。它消耗更少的内存(因为StAX的使用),但是,比大多数SOAP引擎工作的更好。

另外,XFire也提供进一步优化性能的方式。其中一种方式就是使用in-JVM传输。如果你知道Web服务正与客户端运行在同一JVM,你可以选择使用本地传输,这将使你的服务更快。在例子的客户端代码中,观察服务端点URL被指定的行:

 [code]String serviceUrl = "http://localhost:8080/websvc/services/Banking";

替换为:

 [code]String serviceUrl = "xfire.local://Banking"; 

你会看到在性能上的一个惊人的提高。

局限性
XFire
具有一些局限性:

l 
在开发Web服务时,一个好的方式是从WSDL开始。大多数SOAP引擎提供从WSDL生成服务存根的工具。XFire也提供了这样的工具。但是,它是基于注释的,因此,需要J2SE5.0。它对于某些仍然使用J2SE 1.4.x的人并不是一个好事,因为我们需要其它的方式来实现客户端。

l 
支持附件,这将被今后的版本责备。(Support for attachments, which is slated for a future release)

l 
Easy-to-follow user guide
。简单的用户手册,这需要XFire团队作大量的工作。

结论
Java
目前的趋势是简化对技术的使用。因此,我们将看到基于POJO的开发的潮流。同时,SOA和Web服务已经成为了业界热点的讨论内容。XFire应运而生。它是POJO能通过最小的努力就被发布为Web服务。因此,它为开发人员带来了极大的方便。同时,由于它与最近标准一致且具有丰富的API,XFire将为高级用户提供更多的机会。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: