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

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 Tomcat 5.5.7 J2SE1.4.2_07环境。这个例子很简单,只做一件事——将资金从一个账户转入另一个账户。一个清晰的JavaBankingSerivce实现了这一工作,它包含一个名为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.xmlXFire本身是一个基于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.warApache Tomcat环境下的webapps目录,并等几秒钟。它将自动启动。应用的全部源代码也都包含在这个war文件中。现在我们的程序已经是一个Web服务了。

我们如何知道Web服务在工作?

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

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

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

开发客户端

可以用SOAP工具开发客户端,如.netApache 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);            
 

        //Return the response
        return serviceResponse;
        
        
    } 
 

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

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

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

一旦例子应用被发布并启动,尝试servlet URLhttp://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)、XMLBeansXML绑定的Java框架(JAXB-Java Architecture for XML Binding)、Castor等的本地数据绑定。数据绑定规定XML请求如何到达Web服务,以及输出的XML响应如何映射到Java对象。

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

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

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

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

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

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

性能

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

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

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

替换为:

       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的开发的潮流。同时,SOAWeb服务已经成为了业界热点的讨论内容。XFire应运而生。它是POJO能通过最小的努力就被发布为Web服务。因此,它为开发人员带来了极大的方便。同时,由于它与最近标准一致且具有丰富的APIXFire将为高级用户提供更多的机会。

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值