目前在Java平台开发WebService主要有两大框架Axis和XFire。对比.net平台WebService开发的简单易用,Axis框架配置比XFire框架的配置要稍显复杂,而且Axis很快要更新到2.0版本,所以本文仅针对XFire框架描述实现WebService的步骤。
应该了解的几个概念
Web Service SOAP WSDL UDDI
XFire 概述
XFire 是 codeHaus 组织提供的一个开源框架,它构建了 POJO 和 SOA 之间的桥梁,主要特性就是支持将 POJO 通过非常简单的方式发布成 Web 服务,这种处理方式不仅充分发挥了 POJO 的作用,简化了 Java 应用转化为 Web 服务的步骤和过程,也直接降低了 SOA 的实现难度,为企业转向 SOA 架构提供了一种简单可行的方式。
XFire 目前最新的版本是 1.2.2 ,目前支持的特性主要包括:
· 支持将 Web 服务绑定到 POJO、XMLBeans、JAXB1.1、JAXB2.0 和 Castor;
· 支持基于 HTTP、JMS、XMPP 等多种协议访问 Web 服务;
· 支持多种 Web 服务业界重要标准如 SOAP、WSDL、Web 服务寻址(WS-Addressing)、Web 服务安全(WS-Security)等;
· 支持 JSR181,可以通过 JDK5 配置 Web 服务;
· 高性能的 SOAP 实现;
· 服务器端、客户端代码辅助生成;
· 对 Spring、Pico、Plexus 等项目的支持等。
XFire 安装包
XFire 框架目前的最新版本是 1.2.6 ,可以访问 xfire.codehaus.org 下载 XFire 框架的安装包,下载时请选择“全部二进制发布包(Binary Distribution in zip package)”,而不仅仅是“XFire jar 文件(Jar of all XFire modules)”。
下载完成后,我们可以将下载的 .zip 文件解压缩到任意的文件夹中(后面的章节中使用 % XFIRE_HOME % 表示 XFire 框架的安装目录),解压缩后形成的文件目录结构如下:
· api(目录)
api 目录中是 XFire 框架中所有类(class)对应的 API 文档,为开发者使用 XFire 完成应用开发提供帮助。
· examples(目录)
examples 目录中包含了所有随 XFire 二进制包发布的实例,包括这些实例的源代码和相关 Web 应用配置内容。
· lib(目录)
lib 目录中包含 XFire 运行所需要的外部支持类包(.jar文件),可以根据不同项目所需的 XFire 特性选择所需要的支持类包。保守的方法是在 Web 项目中包含所有的外部支持类包(.jar文件)。
· manual(目录)
manual 目录中包含有 XFire 框架的帮助文档,开发者可以从这些帮助文档中学习更多运用 XFire 框架实现 SOA 的知识和技巧。
· modules(目录)
modules 目录中包含了 XFire 框架根据不同特性分别编译的二进制包文件。发布基于 XFire 框架的 Web 项目时,可以选择使用该目录下的所有 .jar 文件,也可以选择 XFire-all- 1.2.6 .jar 文件。
· XFire-all- 1.2.6 .jar
XFire 框架的二进制包文件,包含了全部的模块(modules)。
· LICENSE.txt
LICENSE.txt 文件中包含了 XFire 框架的授权协议。
· NOTICE.txt
· README.txt
这两个文件中包含了 XFire 发布时的一些有用的信息。
XFire 框架支撑环境
XFire框架是一种基于Servlet技术的SOA应用开发框架,要正常运行基于XFire应用框架开发的企业应用,除了XFire框架本身之外,还需要JDK和Servlet容器的支持。
1.JDK 版本选择、下载和安装
XFire 支持非常多的特性,其中不同的特性对 JDK 版本的要求有所不同,比如如果项目中选择基于 JSR181 标准发布 Web 服务,我们就需要选择 JDK5 或者以上版本,如果仅仅选择将 Web 服务绑定到最简单的 POJO,我们只需要选择 JDK1.4 版本即可。
JDK 各版本均可以在 java.sun.com 网站上下载,如何安装 JDK 请参考 SUN 公司的相关技术文档和 JDK 的帮助文档。
2.Servlet 容器下载和安装
XFire 是一种基于 Servlet 技术的 SOA 应用开发框架,需要 Servlet 容器的支持。XFire 支持在多种 Servlet 容器中运行,包括 Websphere、Weblogic、TOMCAT 等。为了说明的简单,我们选择使用 TOMCAT(版本5.0)作为 XFire 的运行容器,所有配置过程和发布步骤的说明也均是针对 TOMCAT,如果读者使用 TOMCAT 之外的其它 Servlet 容器或者选择了 TOMCAT 的其它版本,下面的配置过程和步骤可能需要做出调整,请读者根据实际 Servlet 容器的帮助文档进行相应调整。
TOMCAT 各版本均可以在 tomcat.apache.org 网站上下载,如何正确安装 TOMCAT 服务器请参考 TOMCAT 服务器的帮助文档。
3.xalan
XFire 需要 xalan 项目的支持,然而 1.2.6 版本中并没有带有相应的 jar 文件,因此请访问 xml.apache.org,下载 xalan 项目的二进制包。
XFire 应用配置
前面的章节中我们下载和安装了 XFire 安装包和所需要的支持环境,现在我们开始学习如何从零开始创建 XFire 应用开发环境。下面的所有配置过程和发布步骤均针对 TOMCAT(版本5.0)服务器,如果选择其它的 Servlet 容器,下面的配置过程和步骤可能需要做出调整,请读者根据实际 Servlet 容器的帮助文档进行相应调整。
XFire 框架中,我们有两种方式将 POJO 发布成 Web 服务:
· 一种方式是直接使用 Web 服务接口和 Web 服务实现类(POJO)来发布;
· 另一种方式是基于 JSR181 标准和注释技术将被注释的 POJO 发布成 Web 服务;
将 POJO 发布成 Web 服务的基本步骤如下:
1. 创建 Web 服务接口,声明该 Web 服务对外暴露的接口;
2. 创建 Web 服务实现类,为 Web 服务接口提供实现;
3. 修改 XFire 框架的服务发布文件 ---- services.xml,将 POJO 发布成 Web 服务。
下面我们通过创建一个简单的例子来具体说明如何实现这三个步骤。
1. 创建Web工程 TestWebService,创建 Web 服务接口 ---- IFirstWebService
要将 POJO 发布成 Web 服务,首先需要创建 Web 服务接口,在接口中声明该 Web 服务需要对外暴露的接口。
我们根据需要创建 Web 服务接口 ” IFirstWebService”,在其中声明一个 ”getInfo”方法,该方法获取一个输入的”String”类型变量,返回 ”String ”类型的内容。
”IFirstWebService”接口对应的 Java 文件代码如 清单 1-1。
清单 1-1
TestWebService/WEB-INF/classes/com/ws/test/IFirstWebService.java
package com.ws.test;
public interface IFirstWebService {
public String getInfo(String name);
}
2.创建 Web 服务实现类----FirstWebService
创建 Web 服务实现类 ” FirstWebService”,它实现了 ”1、创建Web服务接口 ---- IFirstWebService” 中创建的IFirstWebService 接口。 ”FirstWebService”类对应的 Java 文件代码如 清单 1-2。
清单 1-2
TestWebService/WEB-INF/classes/com/ws/test/FirstWebService.java
package com.ws.test;
public class FirstWebService implements IFirstWebService{
public String getInfo(String name)
{
return "Hello "+name+" this a First Web Service.";
}
}
3.修改 services.xml,将 POJO 发布成 Web 服务
我们可以在 WEB-INF/classes/META-INF/XFire/services.xml 文件中的 <beans …> 和 </beans> 元素中间加入如下的 xml 内容将上面创建的 IFirstWebService 发布成 Web 服务。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xfire.codehaus.org/config/1.0">
<service>
<name>ws</name>
<namespace>firstws</namespace>
<serviceClass>com.ws.test.IFirstWebService</serviceClass>
<implementationClass>com.ws.test.FirstWebService</implementationClass>
</service>
</beans>
其中各元素的功能如下:
· service
service 标签和它所包含的 xml 内容为发布成 Web 服务的 POJO 提供完整的描述。
· name
Web 服务被发布时所采用的唯一名称。可以是你提供任何的合法名字。这将会被客户端程序和其它需要定位你的服务的组件用到。例如,在服务准备好以后,你将在浏览器上使用这个名字来查看WSDL。
· namespace
Web 服务发布时所使用的命名空间。用来唯一标识你的服务的各个参数。
· serviceClass
Web 服务接口类的全名,包括包名和类名。包含了Java类的名字,它指定了方法签名。在本例中,它是接口IFirstWebService。如果Java类没有实现任何接口,你就需要把类的名字放在这里。在你的Java类或者接口中可能有几个方法。只需要一个入口把它们全部发布为Web Services。
· implemetationClass
Web 服务实现类的全名,包括包名和类名。保存了实现方法的Java类名。这是一个可选元素。如果上一个元素<serviceClass>包含了一个接口,那么相应的实现类必须在这里指定。
更多 service 元素的子元素和它们的用法请参考 XFire 站点。
通过上面的三个步骤,我们已经将新创建的IFirstWebService发布成了Web服务,我们可以使用下面的步骤测试一下创建的Web服务是否能够正常运行:
1. 编译上面的步骤中创建的 Java 接口和类;
2. 启动 TOMCAT 服务器。
3. 等 TOMCAT 服务器完全启动后,打开浏览器,在地址栏中输入 http://localhost:8080/TestWebService/services/ws?wsdl
其中 ws 是配置文件中 service/name 元素所定义的内容,”wsdl”参数表示查看该 Web 服务的 WSDL(Web服务描述语言)文件。
如果浏览器中出现如下图所示类似的内容,表示 Web 服务发布成功,我们可以编写客户端访问该 Web 服务从服务器获取返回字符串。
图:浏览器中访问效果
如果浏览器中出现错误提示,请按照上面的步骤和说明检查已经完成的开发、配置过程是否完全正确。
开发一个客户端
你可以使用任何的SOAP工具创建客户端,例如,.Net或者Apache Axis,有很多种方法:使用从WSDL产生的stubs,使用动态代理,等等。在例子中,我们使用一个动态代理,以一个简单的Servlet形式,叫做CallFirstWebService.java。对Web Service的实际调用由CallWS(String name)方法完成,它相当地简单。代码如下:
package com.ws.client;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.ws.test.*;
public class CallFirstWebService extends HttpServlet {
public CallFirstWebService() {
super();
}
public void destroy() {
super.destroy();
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String str = "";
response.setContentType("text/html");
PrintWriter out = response.getWriter();
try{
str = this.CallWS("Everyone");
}
catch(Exception e){
str = e.getMessage();
}
out.println("<!DOCTYPE HTML PUBLIC /"-//W 3C //DTD HTML 4.01 Transitional//EN/">");
out.println("<HTML>");
out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>");
out.println(" <BODY>");
out.print(" This is ");
out.print(this.getClass());
out.println(", using the GET method");
out.println("<P><h1>"+str+"</h1><p>");
out.println(" </BODY>");
out.println("</HTML>");
out.flush();
out.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
public void init() throws ServletException {
}
public String CallWS(String name) throws MalformedURLException, Exception
{
//创建元数据
org.codehaus.xfire.service.Service serviceModel = new org.codehaus.xfire.service.binding.ObjectServiceFactory().create(FirstWebService.class);
//创建代理
org.codehaus.xfire.XFire xfire = org.codehaus.xfire.XFireFactory.newInstance().getXFire();
org.codehaus.xfire.client.XFireProxyFactory factory = new org.codehaus.xfire.client.XFireProxyFactory(xfire);
String serviceURL = "http://localhost:8080/TestWebService/services/ws";
FirstWebService client = null;
try{
client = (FirstWebService)factory.create(serviceModel,serviceURL);
}
catch(MalformedURLException e){
throw e;
}
//调用WebService
String serviceResponse = "";
try{
serviceResponse = client.getInfo(name);
}
catch(Exception e1)
{
throw e1;
}
return serviceResponse;
}
}
这个代码是如何工作的呢?我来解释一下:首先,我们创建一个服务模型,它包含服务的说明——换句话说,就是服务的元数据。我们使用XFire的ObjectServiceFactory从IFirstWebService.class接口创建这个模型。
接着,为XFire获得一个代理工厂对象,它包含了常规的代码,也相当地简单和易懂。这一步中没有任何特定应用的东西。从这个proxyFactory,使用服务模型和服务端点URL(用来获得WSDL),我们可以得到一个服务的本地代理。
就是它了。这个代理就是实际的客户端。现在,我们可以调用它的getInfo(String name)方法来得到我们需要的Web Service。
一旦示例应用发布并启动,就可以尝试servlet URL:
http://localhost:8080/TestWebService/servlet/CallFirstWebService
补充
Web Services需要消耗很多资源,但是性能方面它们不是那么引人注目。XFire打破了这种趋势。它消耗更少的内存(部分因为 StAX的使用),但是表现却比多数可比较的SOAP引擎出色。你可以在资源中提供的链接中看到比较的结果。
此外,XFire还提供了各种方法来进一步优化性能。一个方法是使用JVM内置传输(in-JVM transport)。如果你知道Web Services和客户端运行在同一个JVM上,你可以选择使用本地传输,它可以大幅提升性能。在示例中的客户端代码,看以下指定服务端点URL的这行:
String serviceURL = " http://localhost:8080/TestWebService/services/ws";
替换为
String serviceURL = "xfire.local://ws";
你会看到性能上的明显提高,因为它绕过了整个网络层。
总结
需要注意以下几点问题
1. 检查Java类的方法和默认构造函数确保为public
2. 增加XFire servlet相关条目到web.xml中
3. 创建services.xml,把它放到WEB-INF/classes/META-INF/xfire目录下
4. 增加XFire和第三方包到你的Web应用的WEB-INF/lib文件夹中
另外,在Eclipse中创建Web Service Project时,默认添加了Eclipse自带的XFire包,我使用Eclipse自带的XFire包未能配置成功,建议按照上文介绍的配置方法,自行下载库包文件进行配置。
结束语
以上就是使用XFire开发WebService的一个完整例程。文中已列出了所有需要了解的概念,使用到的库包,程序的源代码和配置文件的源代码,程序非常简单,重点在于掌握XFire的配置流程和思想。希望这篇文章能够对还不了解如何在Java平台实现WebService的朋友有所帮助。