为了实现Web Services的平台无关性和实现访问独立性,软件行业需要遵循一些作为标准的技术。其中一些包括:
---XML:在Web Services环境中各层之间进行传递的默认数据格式。
下面的高级层次图表,基于WWW协会发布的“Web Services Architecture”(Web Services架构)文档,显示了这些技术在实际的工作环境中是如何发挥作用:
这个流程图显示了Web Services中的核心技术是如何工作的。
这里,Provider是提供服务的应用程序组件,Requester是使用服务的客户端程序。很多其他技术也会参与到交互中,但是这个图只显示了在Web Services环境中必需的核心技术组件。
XFire是一个免费的开源SOAP框架,它不仅可以极大方便地实现这样一个环境,并且可以提供许多Web Services规范中高级特征,这些特征在多数的商业或者开源工具都没有提供。你要恰当的理解这些单词:great ease and simplicity(非常轻松和简单)。你将会看到使用XFire创建Web Services是多么的简单。
package com.mybank.xfire.example; import java.text.NumberFormat; /** XFire WebServices sample implementation class. |
因为使用接口的设计是一个好的实践,所以我们的Java类也实现了一个称为IBankingService的接口。代码十分简单:
package com.mybank.xfire.example; public interface IBankingService { public String transferFunds( |
在实际实现中,这样一个方法可能包括各种类型的复杂调用、查询和处理操作。但是我们的示例代码已经最小化了,以至于我们可以集中精力在主要目标上:把这个方法发布为Web Services。
你可以看到BankingService是一个普通的Java类,没有任何代码告诉我们它将会在Web Services中使用。好的,这里我们不需要增加任何东西。我们所有的工作都在部署描述符里完成。
Web应用的部署描述符
在Java中,Web应用程序通常需要至少一个部署描述符(叫做web.xml)对其进行配置。XFire本身是一个基于servlet的应用程序。因此,我们需要增加必要的引用到描述符文件中。然后我们还必须配置将要创建的Web Services。我们使用一个称为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> |
<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> |
<implementationClass>保存了实现方法的Java类名。这是一个可选元素。如果上一个元素<serviceClass>包含了一个接口,那么相应的实现类必须在这里指定。
- • activation-1.0.2.jar
- • commons-codec-1.3.jar
- • commons-httpclient-3.0.jar
- • commons-logging-1.0.4.jar
- • jaxen-1.1-beta-8.jar
- • jdom-1.0.jar
- • log4j-1.2.x.jar
- • mail-1.3.3_01.jar
- • spring-1.2.x.jar
- • stax-api-1.0.jar
- • wsdl4j-1.5.2.jar
- • wstx-asl-2.9.jar
- • xbean-2.1.0.jar
- • xbean-spring-2.2.jar
- • xfire-all-1.0.jar
- • XmlSchema-1.0.jar
我们如何知道Web Service正在工作呢?
为了了解Web Service是否正在工作,我们需要测试。首先,我们测试来看WSDL是否可用。我们在浏览器中输入URL。哪个URL?因为我们的应用程序的war文件是websvc.war,并且在services.xml中给出的服务名是Banking,WSDL的URL应该是:http: //localhost:8080/websvc/services/Banking?wsdl。
请注意:URL的第一部分,例如,http://localhost:8080,可能会根据你的应用服务器不同而不同。无论怎样,当你输入URL后,将会看到一个XML文档,它的根元素是 。这个文档叫做服务的WSDL。如果你看到了,这就是你的应用作为Web Service已经可用的第一个证明。
但是这个测试是不够的。可能会发生这种情况,可以看到WSDL,但是从客户端程序可能会访问不到服务。因此为了核实服务是否可以访问了,我们必须使用一个客户端进行服务的实际调用来进行一个真正的测试。
开发一个客户端
你可以使用任何的SOAP工具创建客户端,例如,.Net或者Apache Axis,有很多种方法:使用从WSDL产生的stubs,使用动态代理,等等。在例子中,我们使用一个动态代理,以一个简单的Servlet形式,叫做 WsClient.java。为了保持代码两最小,所有在屏幕显示的元素都放在了doGet()方法中。对Web Service的实际调用由callWebService()方法完成,它相当地简单。和下面的类似:
/* Call the Web service //Return the response |
这个代码是如何工作的呢?我来解释一下:首先,我们创建一个服务模型,它包含服务的说明——换句话说,就是服务的元数据。我们使用XFire的ObjectServiceFactory从IBankingService.class接口创建这个模型。
接着,为XFire获得一个代理工厂对象,它包含了常规的代码,也相当地简单和易懂。这一步中没有任何特定应用的东西。从这个proxyFactory,使用服务模型和服务端点URL(用来获得WSDL),我们可以得到一个服务的本地代理。
就是它了。这个代理就是实际的客户端。现在,我们可以调用它的transferFunds()方法来得到我们需要的Web Service。
http://localhost:8080/websvc/ws。
这个Servlet使用默认参数来调用Web Service和显示接收到的响应。页面的最后两行应该读取:
现在你可以确定Web Service已经发布并且在运行中了。
http://localhost:8080/websvc/ws?from=11-2345&to=77-9876&amt=250.00&cur=EUR。
这个清单总结了将一个Java方法发布为Web Service所必须的步骤:
- 1、 检查Java类的方法和默认构造函数确保为public
- 2、 增加XFire servlet相关条目到web.xml中
- 3、 创建services.xml,把它放到WEB-INF/classes/META-INF/xfire目录下
- 4、 增加XFire和第三方包到你的Web应用的WEB-INF/lib文件夹中
XFire的使用可能比较简单,但是在特性和功能性上,它却占据着领导者的位置。下面是它的高级特性:
- ---本地数据绑定支持POJOs(plain-old Java objects)、XMLBeans、JAXB(Java Architecture for XML Binding)、Castor等等。数据绑定说明了Web Services的XML请求和映射到Java对象的XML响应。
- ---使用StAX(Streaming API for XML)处理XML文档。同DOM的基于树和SAX的事件驱动的处理方式相比,StAX使用了拉(pull)机制,它使处理更快速,内存效率更高。
- ---支持多种传输协议,如HTTP、JMS(Java Message Service)和JVM内部传输。
- ---嵌入式,这是XFire的核心功能之一。你可以把这个SOAP引擎嵌入到你的应用中,完全隐藏所有XFire特定引用,同样所有配置都是程序驱动。
- ---丰富的API,它使XFire可高度自定义,允许开发者在不同的阶段截获请求,并且对他们进行处理。
- ---兼容最新的标准例如SOAP1.1(没有加密远程工程调用,或者RPC)和1.2、WSDL1.1、the Web Services Interoperability Organization’s Basic Profile 1.0、Web Services Addressing和WS-Security。
String serviceUrl = "http://localhost:8080/websvc/services/Banking";