使用 JBossWS 创建简单的 Web 服务
一篇关于如何使用 JBossWS 创建简单的 Web 服务、如何部署和测试的文章。
引言
前段时间,我被分配到一个项目,需要创建一个在 JBoss 应用服务器上运行的简单 Web 服务。当我搜索网络以获取一些详细教程时,我没有找到任何能帮助我的详细教程。最终,我弄清楚了设计和实现这样一个 Web 服务需要的所有组件。我决定将我学到的东西总结在这篇文章中,这不仅是为了我自己的记录,也是为了帮助其他需要类似信息的人。
本文旨在提供关于以下主题的详细教程
- 本文所需的软件
- 如何为 JBoss 应用服务器创建简单的 Web 服务?
- 如何将 Web 服务部署和取消部署到 JBoss 应用服务器?
- 如何设计一个简单的测试应用程序来测试正在运行的 Web 服务?
希望读者会喜欢这篇文章!如果您有任何问题或意见,请在下面的评论区留言。
背景
在搜索详细教程时,我从这个指南中获得了极大的帮助。但是,这个指南的缺点是缺乏某些细节。对于一些高级开发者来说,这可能非常明显,但没有这些细节,许多初学者可能会感到困惑。本文旨在填补这些空白。我建议读者在阅读我的文章后也回顾一下这个指南。
安装和配置所需软件
本教程需要设置和配置以下软件包
- JDK 1.5 (或更高版本)
- Apache Ant (当前版本为 1.7.1)
- JBoss 应用服务器 (当前版本为 5.0.0 GA)
- JBossWS (当前版本为 3.0.5 GA)
我也推荐使用 Eclipse IDE。但是,在本教程中,所有工作都可以使用简单的代码编辑器(如 UltraEdit32、Crimson Editor 或 Notepad++)、命令提示符和 Apache Ant 来完成。
为了方便起见,本教程是在 Windows XP 上创建的。将其迁移到其他平台应该相对容易。
安装 JDK 和 Apache Ant
在 Windows XP 上安装 JDK 非常简单,只需下载 MSI 安装程序,然后将其安装到“Program Files”或直接安装到“C:\”。安装 JDK 后,建议配置系统变量
- 创建系统环境变量“
JAVA_HOME
”并将其指向 JDK 的基本目录(即 C:\Program Files\Java\jdk-1.5.0_17 或 C:\jdk-1.5.0_17)。 - 还将“
%JAVA_HOME%\bin
”添加到系统变量“PATH
”中。
配置完系统变量后,打开命令提示符并键入“java -version
”。输出将显示系统中安装的 JDK 版本。这有助于验证 JDK 安装是否成功。验证后,关闭命令提示符。
安装 Apache Ant 也非常简单,请从 Apache Ant 项目网页(此处)下载二进制可执行存档文件。然后将存档文件解压到“C:\”。这将把存档文件解压到“C:\apache-ant-1.7.1”。“C:\apache-ant-1.7.1”将是 Apache Ant 的基本目录。解压后,还需要按如下方式配置系统变量
- 创建系统环境变量“
ANT_HOME
”并将其指向 Apache Ant 的基本目录(即 C:\apache-ant-1.7.1)。 - 还将“
%ANT_HOME%\bin
”添加到系统变量“PATH
”中。
配置完系统变量后,请打开命令提示符并键入“ant -version
”进行验证。如果配置正确,输出将显示系统中安装的 Apache Ant 版本。
安装 JBoss 和 JBossWS
本教程讲授如何在 JBoss 中创建 Web 服务。因此,安装和配置 JBoss 应用服务器(当前版本 5.0.0.GA)和 JBoss Web Services(也称为 JBossWS,当前版本 3.0.5.GA)也是必需的。您可以在以下两个位置找到安装包(zip 存档):
- JBoss 应用服务器下载,请注意,在实际下载页面中,有两个存档文件,与 JDK 1.5 兼容的是 jboss-5.0.0.GA.zip。另一个(jboss-5.0.0.GA-jdk6.zip)与 JDK 1.6 兼容。
- JBoss Web Services 下载
安装 JBoss 的过程与安装 Apache Ant 类似。您只需要将包含 JBoss 应用服务器二进制可执行文件的存档文件解压到“C:\”。这将创建一个名为“C:\jboss-5.0.0.GA”的新目录,它是 JBoss 应用服务器的基本目录。解压后,创建系统环境变量“JBOSS_HOME
”并将其指向“C:\jboss-5.0.0.GA”。虽然可选,但您也可以将“%JBOSS_HOME%\bin
”添加到系统变量“PATH
”中。
最后一步是安装 JBossWS 包。步骤如下
- 首先将 JBossWS 二进制可执行存档解压到“C:\”。这将创建文件夹“C:\jbossws-native-bin-dist”。
- 从 Windows 资源管理器中,导航到“C:\jbossws-native-bin-dist”。在此文件夹中,找到文件“ant.properties.example”。
- 复制“ant.properties.example”,然后将其重命名为“ant.properties”。
- 启动您喜欢的代码编辑器(如 UltraEdit32 或 Notepad++),然后打开“ant.properties”进行编辑。
- 找到行“
jboss500.home=@jboss500.home@
”,将其更改为“jboss500.home=/jboss-5.0.0.GA
”。然后保存并关闭代码编辑器。 - 打开命令提示符,导航到“C:\jbossws-native-bin-dist”。然后运行命令“
ant deploy-jboss500
”。如果成功完成,JBossWS 将被正确安装和配置以供使用。
创建简单的 Web 服务
现在我们可以创建一个简单的 Web 服务了。有两种创建 Web 服务的方法
- 自顶向下。使用 JBossWS 从现有的 WSDL 和关联的 XSD 文件创建代理类。然后实现 Web 服务端口接口。
- 自底向上。通过 POJO 创建一个简单的 Web 服务。然后打包类进行部署。
在本教程中,将讨论自底向上方法,因为这是创建 Web 服务最简单的方法。源代码可在下载部分找到。步骤将在以下子节中讨论。
创建一个简单的 Java 项目
本教程使用 Eclipse IDE 和 Apache Ant 来构建示例项目。创建这个示例项目与创建简单的 Java HelloWorld
项目没有区别。获取示例源代码后,您会发现基本目录“webservice”中有两个文件夹
- “bin”:此文件夹用于存放构建输出。
- “src”:此文件夹包含源代码。源代码文件“Greeting.java”可以在子文件夹 tutorial/hanbo/webservice 下找到。
在基本目录中,有许多文本文件
- .classpath:此文件由 Eclipse 自动生成。
- .project:此文件也由 Eclipse 自动生成。
- build.xml:这是 Apache Ant 构建文件。
首先,让我们看一下源代码文件“Greeting.java”。整个源代码如下所示
package tutorial.hanbo.webservice;
import javax.jws.WebService;
import javax.jws.WebMethod;
@WebService
public class Greeting
{
@WebMethod
public String greetClient(String userName)
{
return "Greeting " + userName + "! Have a nice day...";
}
}
这是创建简单 Web 服务所需的全部 Java 代码。让我们详细检查一下源代码
- 第一行声明了 Web 服务的包。
- 接下来的两行代码导入了所需的类。它们是用于类声明和方法声明的注解。
- 声明一个名为“
Greeting
”的类;它用“WebService
”进行注解,这意味着“Greeting
”类是一个 Web 服务。 - 在“
Greeting
”类内部,声明一个名为“greetClient()
”的public
方法。它用“WebMethod
”进行注解,这意味着此方法是一个可以远程调用的 Web 方法。- 方法“
greetClient()
”接受一个名为“userName
”的String
类型参数。其主体将创建一个新的String
对象并返回。
- 方法“
如果未将引用库添加到此项目中,项目将无法在 Eclipse 中编译。所以请查看 .classpath 文件,并查看所有必需的引用库(即,引用 jar 文件)。这些库是 JBoss
包的一部分。它们可以在 3 个不同的文件夹中找到
- C:\jboss-5.0.0.GA\client
- C:\jboss-5.0.0.GA\lib
- C:\jboss-5.0.0.GA\lib\endorsed
只需将这三个文件夹中的所有 jar 文件添加到示例项目中,所有编译错误就会消失。但是,有两个 jar 文件必须删除,它们是
- C:\jboss-5.0.0.GA\client\jaxws-rt.jar
- C:\jboss-5.0.0.GA\client\jaxws-tools.jar
必须从项目中删除它们的原因是为了避免异常。这可能是 JBossWS 的一个奇怪的 bug。当我第一次处理这个示例时,在尝试将完成的 Web 服务部署到 JBoss 应用服务器时遇到了异常。在搜索 Google 结果后,我找到的解决方案是删除项目类路径中的这两个 jar 文件。
部署描述符
Web 服务必须部署才能被客户端访问。在本教程中,Web 服务将打包成 war 文件并作为 servlet 部署。war 文件包含一个部署描述符,“web.xml”文件指定 URL.Servlet
映射。当请求发送到 JBoss 应用服务器时,JBoss 将根据 web.xml 文件中指定的 URL/Servlet 映射将请求路由到特定的 servlet。
在项目的基本目录中,您可以在 src/resources 子目录中找到 web.xml 文件。该文件的内容如下所示
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
"http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
<web-app>
<servlet>
<servlet-name>GreetingWebService</servlet-name>
<servlet-class>tutorial.hanbo.webservice.Greeting</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>GreetingWebService</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
此描述符文件的内容很容易理解。整个内容分为两部分
- 第一部分(从
<servlet>
到</servlet>
)指定了 servlet 是什么。它有一个名为“GreetingWebService
”的名称,并映射到 Java 类“tutorial.hanbo.webservice.Greeting
”。 - 第二部分(从
<servlet-mapping>
到</servlet-mapping>
)指定了 URL 到 servlet 的映射。如果请求 URL 指向 Web 服务,那么请求将由 Web 服务处理。
下一节将介绍如何打包 war 文件。
使用 Apache Ant 打包
可以使用 Apache Ant 打包 war 文件。在 build.xml 中,您可以找到多个目标。它们用于执行构建操作。其中一个目标名为“packaging
”。这是用于创建 war 文件进行部署的目标,如下所示
<target name="packaging" >
<war destfile="bin/greeting.war" webxml="src/resources/web.xml">
<classes dir="bin/classes"/>
</war>
</target>
在此 target
部分,只有一个操作要执行——使用名为“war
”的任务来构建 war 文件。此任务接受三个参数
destfile
:这是 XML 标签“war
”的第一个属性,用于指定 war 文件名以及它将在哪个文件夹中输出。webxml
:这是 XML 标签“war
”的第二个属性,用于指定在哪里找到 web.xml 文件,该文件将被打包到 war 文件中。classes
:这是 XML 标签“war
”下的一个子 XML 标签,用于指定要包含在 war 文件中的类文件。
要运行此目标,您只需要在命令提示符中使用以下命令
> ant packaging
命令的输出如下所示
Buildfile: build.xml
packaging:
[war] Building war: %project_base_directry%\bin\greeting.war
BUILD SUCCESSFUL
Total time: 1 second
在项目基本目录下的 bin 目录中,您将找到新创建的 war 文件。使用 7-zip 等 zip 压缩/解压缩工具,您可以打开此存档文件并探索其内部结构。内部有两个目录,一个称为“META-INF”,其中包含“MANIFEST.MF”文件;另一个称为 WEB-INF,里面有一个名为“classes”的子目录和一个名为“web.xml”的文件。Greeting.class
在 WEB-INF/classes 下的“tutorial/hanbo/webservices”子目录中。
既然 war 文件已成功构建,就该进行部署了。
部署和取消部署
在尝试将示例 war 文件部署到 JBoss 应用服务器之前,您必须先启动 JBoss 应用服务器。由于我们只是使用 JBoss 作为测试简单 Web 服务的一种方式,本教程将不讨论如何将 JBoss 作为服务运行。相反,我们将打开另一个命令提示符,然后在新打开的命令提示符中启动 JBoss 应用服务器。
要启动 JBoss 应用服务器,请使用新打开的命令提示符导航到“C:\jboss-5.0.0.GA\bin”,然后运行启动脚本“run.bat”。JBoss 应用服务器启动后,您需要等待片刻,直到命令提示符显示如下输出
15:34:41,889 INFO [ServerImpl] JBoss (Microcontainer)
[5.0.0.GA (build: SVNTag=JBoss_5_0_0_GA date=200812041714)] Started in 5m:3s:150ms
上述输出表示 JBoss 应用服务器已成功启动。
要关闭 JBoss 应用服务器,请激活运行 JBoss 应用服务器的命令提示符。按 Ctrl+C 停止执行,然后关闭命令提示符。
要部署 war 文件,您只需要复制 war 文件(greeting.war),然后将其粘贴到“C:\jboss-5.0.0.GA\server\default\deploy”。完成此步骤后,您会注意到 JBoss 应用服务器正在运行的命令提示符将显示部署进度,如下所示
15:35:21,422 INFO [DefaultEndpointRegistry]
register: jboss.ws:context=greeting,endpoint=GreetingWebService
15:35:22,453 INFO [TomcatDeployment] deploy, ctxPath=/greeting, vfsUrl=greeting.war
15:35:28,172 INFO [WSDLFilePublisher] WSDL published to:
file:/C:/jboss-5.0.0.GA/server/default/data/wsdl/greeting.war/GreetingService4604908665079984702.wsdl
上述输出基本上表明部署过程成功。
下一步是测试部署。打开浏览器窗口,然后导航到“https://:8080/jbossws/services”。页面加载后,您应该能在“已注册的服务端点”部分看到关于部署 Web 服务“GreetingWebService
”的详细信息。您可以尝试的另一个测试是查看 JBossWS 动态生成的 WSDL 文件。对于本教程,生成的 WSDL 的链接是“http://127.0.0.1:8080/greeting?wsdl”。您可以使用相同的浏览器窗口查看。
通过简单地删除“C:\jboss-5.0.0.GA\server\default\deploy”中的 war 文件(greeting.war)即可取消部署 Web 服务。完成此操作后,命令提示符将显示取消部署的进度
16:51:12,229 INFO [TomcatDeployment] undeploy, ctxPath=/greeting, vfsUrl=greeting.war
16:51:13,307 INFO [DefaultEndpointRegistry] remove: jboss.ws:context=greeting,
endpoint=GreetingWebService
上述输出基本上表明取消部署过程成功。
在 build.xml 中,提供了两个目标来部署或取消部署 Web 服务。它们只是使用 Apache Ant 的复制文件和删除文件任务来完成部署和取消部署操作。要部署 Web 服务,请使用目标“deploy
”。要取消部署 Web 服务,请使用目标“undeploy
”。
使用 Web 服务客户端测试 Web 服务
如果您不测试新创建的 Web 服务,您将无法知道它是否正常工作。由于在本教程中,Web 服务非常简单,只公开了一个接受 string
作为参数的 Web 方法,因此可以通过动态调用来测试它。正如许多其他人所说,“动态调用是创建 Web 服务客户端的糟糕方法”。现实世界中的大多数 Web 服务都利用复杂的数据对象并执行复杂的操作。使用动态调用创建代码来执行这种复杂的 Web 服务可能极其困难。最好使用 JBossWS 从 WSDL 和关联的 XSD 文件生成的代理类来创建 Web 服务客户端。
Web 服务客户端是一个用 Java 编写的控制台应用程序。我已经将这个测试应用程序分离到一个名为“webservice-test
”的单独项目中。该项目使用与 Web 服务项目相同的引用 jar 集。提供了 build.xml 文件,不仅可以在命令提示符下构建项目,还可以运行测试应用程序。要构建项目,请使用命令“ant compile
”。构建项目后,要运行测试应用程序,请使用命令“ant run-test-app
”。但是,在运行此测试应用程序之前,请务必先部署示例 Web 服务。
让我们看一下测试应用程序的源代码。源代码的两个主要部分是
import
语句,用于导入 Web 服务客户端使用的许多类。- 包含程序执行流程的
main
方法。
导入语句如下所示
import javax.xml.rpc.Call; import javax.xml.rpc.Service; import javax.xml.rpc.ServiceFactory; import javax.xml.rpc.ParameterMode; import javax.xml.namespace.QName;
如上面的代码所示,我们只导入了所需的类。ServiceFactory
类用于创建 Service
对象。Service
对象能够创建一个 call
对象。使用 Call
对象,我们可以对 Web 服务公开的 Web 方法执行远程过程调用。由于 Web 方法接受输入参数,我们将需要 ParameterMode
来指定如何使用该参数。由于生成的 WSDL 也使用命名空间,因此我们还需要 QName
对象来表示限定名称。
以下代码将调用示例 Web 服务
public static void main(String[] argv) { try { String NS_XSD = "http://www.w3.org/2001/XMLSchema"; ServiceFactory factory = ServiceFactory.newInstance(); Service service = factory.createService( new QName( "http://webservice.hanbo.tutorial/", "GreetingService" ) ); Call call = service.createCall(new QName( "http://webservice.hanbo.tutorial/", "GreetingPort" )); call.setTargetEndpointAddress( "https://:8080/greeting?wsdl" ); call.setOperationName( new QName( "http://webservice.hanbo.tutorial/", "greetClient" ) ); QName QNAME_TYPE_STRING = new QName(NS_XSD, "string"); call.setReturnType(QNAME_TYPE_STRING); call.addParameter( "arg0", QNAME_TYPE_STRING, ParameterMode.IN ); String[] params = { "Murphy Brown" }; String result = (String)call.invoke(params); System.out.println(result); } catch (Exception e) { e.printStackTrace(); } }
这段代码展示了动态调用是如何工作的。正如您所见,它相当复杂。逻辑如下
- 首先,创建一个
ServiceFactory
对象。 - 然后调用
ServiceFactory
对象的createService()
来创建一个Service
对象。传入的参数是QName
对象。QName
对象表示名为“GreetingService
”的服务,其namespace
为“http://webservice.hanbo.tutorial/”。
- 使用新创建的
Service
对象的createCall()
方法来创建一个Call
对象。Call
对象代表 Web 服务端口。 - 对于
Call
对象,我们需要- 设置目标端点地址(
setTargetEndPointAddress()
)。这是指向动态生成的 WSDL 的 URL。 - 设置操作名称(
setOperationName()
)。这是我们要调用的 Web 方法的名称。 - 设置返回值类型(
setReturnType()
)。在这种情况下,返回值是标准的string
值。 - 添加传入参数(
addParameter()
)。在这种情况下,唯一的传入参数是一个string
参数。
- 设置目标端点地址(
- 设置完
Call
对象后,我们就可以通过调用Call
对象的invoke()
方法来调用 Web 方法了。传递给invoke()
的参数是一个对象数组,代表远程 Web 方法将使用的输入参数。在这种情况下,只有一个参数。它是一个string
“Murphy Brown
”。
如果一切顺利,该应用程序可以通过 Eclipse 或命令提示符中的 Apache Ant 运行。如果您选择通过 Apache Ant 运行它,命令是
> ant run-test-app
如果一切顺利,输出将如下所示
> ant run-test-app
Buildfile: build.xml
run-test-app:
[java] Greeting Murphy Brown! Have a nice day...
BUILD SUCCESSFUL
Total time: 8 seconds
兴趣点
就这样。这就是如何创建、部署和测试最简单的 Web 服务。我知道以其当前形式,该 Web 服务毫无用处。我喜欢认为本教程提供了一个 Web 服务的骨架。任何读者都可以将其用作起点;添加更多功能,部署和测试;然后添加更多功能,再次部署和测试,直到最终产品能够满足真实用户的需求。
希望您喜欢这篇文章,就像我喜欢写它一样。
历史
- 2009/4/2:修订完成
- 2009/3/2:开始修订
- 2009/2/2:初稿