向业务流程添加Web service基础架构会带来以下几点益处。第一,现有的源代码(不管是基于PC机还是大型机)和所有的开发投资都不会化为乌有,而是将通过新的Web接口继续发挥作用。第二,新的业务事务很容易通过Web处理,并能够与任何新系统或者公开为标准Web service的传统系统相交互。第三,业务事务变得富有意义,这在某种程度上要归功于SOAP和XML标准。第四,如果Web service设计良好的话,所需的流程控制应该最少。第五,由于会话通过HTTP连接完成,所以有可能不受防火墙的限制。当然,实现Web service还有很多其他好处。所以,对于任何公司,Web service都有很高的ROI(投资回报率)。
在本文中,我将说明如何使用企业级工具(如:JBuilder X或JBuilder 2005 Enterprise以及BEA WebLogic Application Server)在现有的Java应用程序的基础上创建简单的Web service。我还将描述Web service的结构、标准、逻辑和相关的平台。为了演示运行中的Web service,我将创建一个具有服务器和客户机的项目。客户机将启动到服务器的真实Web service会话。我还将简要描述如何使用可免费得到的工具(如:Eclipse IDE和 Axis Toolkit)来完成相同的任务。
宿主环境
要获得运行的Web service,必须有一个能驻留该服务的应用服务器。Web service可以选择在任何公共的UDDI(Universal Description, Discovery and Integration,统一描述、发现和集成协议)注册库注册,或在驻留在应用服务器上的本地UDDI注册库注册。UDDI向潜在的业务客户机提供地址薄功能;它允许客户机定位特定服务,并描述了哪种API可用。如果没有UDDI注册库,业务客户机可以(并且常常会)直接转向一个Web service URL并请求WSDL(Web Service Definition Language,Web service描述语言)文档,文档中同样包含有关提供了哪些API的详细描述。WSDL是驻留在应用服务器中的XML文档。
在真实的业务环境中,WSDL不仅要定义所有可用的方法,还要定义所有事务的模式。WSDL旨在被Web service程序识别,帮助它创建具有客户端可以调用的方法的对象存根;因此,WSDL文件是通过将用来创建Web service的工具箱自动生成的。
Web service以Web应用程序的形式驻留在应用服务器上的Web service容器中。任何感兴趣的客户机都可以启动常规HTTP会话与其交互。我们将使用BEA WebLogic应用服务器来建立Web service,它是业内的主流平台之一。若用于开发,BEA WebLogic应用服务器可以免费使用,用于生产则需要许可证。作为替代方案,也可以使用免费的Tomcat应用服务器和Axis工具箱,或者使用Jetty应用服务器和Axis工具箱。当然还有其他应用服务器,典型的应用服务器如JBoss、Sun Microsystems的SunOne、IBM的WebSphere,但这些不在本文的讨论范围之内。所有这些Web平台都能够驻留Web应用程序和Web services。但从开发的角度来说,JBuilder X或2005 Enterprise在创建Web services方面非常灵活易用。
BEA Weblogic的安装非常简单,但需要配置JBuilder来挂钩应用服务器。说明如下:进入JBuilder,在Tool菜单下,单击Configure Servers来建立应用服务器设置。
创建传统项目
在JBuilder中新建一个项目。在该项目下新建一个“beanexport”程序包,并添加一个名为Bean1的类。同时创建另一个名为Tuple的类(参见本文结尾处的清单1)。tuple类中有一对字符串,该类用于演示由一个Web service发送的更复杂的对象,该对象是可选的,不一定要使用。
将代码公开为Web service
为演示如何包装现有的“传统”API并将其转换为全功能的Web service,考虑一个极其简单的名为Bean1的Java类,它只有三个方法。第一个方法总是返回一个随机数,第二个返回一个“Hello”字符串,第三个返回更复杂的对象。
该类公开了一个只有三个方法的公共API,而现实中的应用程序所包含的API要复杂的多。一个企业应用程序可能包含上百个方法,这些方法从数据库、EJB或大型机调用包装器返回值。其中一些方法会带参数,另一些则启动业务事务会话。但是,将任何复杂的API转换为Web服务API就如同这个示例类一样容易。
package beanexport;import java.io.Serializable;public class Bean1 implements Serializable { public double getDouble(){ return Math.random(); } public String getText(){ return "Hello"; } public Tuple getHeader(){ Tuple t = new Tuple("Vlad","Kofman"); return t; }}
关于Tuple对象源,请参见清单1。
创建Web服务
假定我们已经在JBuilder中建立了Bean1 Java项目,并且可以成功编译,而BEA Weblogic Server正在正常运行,那么现在Bean1类就可以公开为Web service。JBuilder真正简化了Web service的创建和部署。打开Bean1项目,执行以下步骤:
- 单击 Project -> Project Properties -> Server。
- 在列出的选项中选择Weblogic。
注意:对于要部署在免费的Tomcat服务器上的Web service,也可以使用Jbuilder来开发;此处也把它列为一个选项。
- 附加的服务配置:项目将驻留在选定的服务(如:EJB)上。也可以选择Servlet和JSP。现在,单击OK。
图3
- 单击 File -> New -> Web Services。
- 单击 New Web Service Configuration (JBuilder X)。
- 选择Weblogic作为工具箱,默认工具箱是Axis(与Tomcat服务器一起使用)。
- 选择服务器和客户机模块。
- 新建Web模块;采用所有默认值。
- 新建应用程序模块;同样采用所有默认值。
- 在下一界面中,将服务器命名为Bean1Server并保存。
JBuilder自动创建所有必需的J2EE(Java 2企业版)标准化文件夹和文件结构。在保存初始配置后,它会打开一个Web Services Designer视图。
接下来的步骤很简单。Bean1项目应该已经具有下列结构(左面板):
- 程序包“beanexport”
- ApplicationModule1模块
- Web-services模块
- Web-services设计工具
取出Bean1类并将其拖放到Web-services设计工具区。或者单击Create Service,从下拉菜单中选择Java Service。
重构Bean1项目;在该项目的各个子文件夹中会自动创建更多文件。就这样,Web service已经开发出来了。接下来只需部署它即可!
考虑JBuilder的作用。 在获得要公开的类后,JBuilder将审查类的所有公共API,并自动生成WSDL定义文件以及所有的SOAP存根和代理,然后将它们打包为WAR和EAR文件(详情见下文),同时准备好特定于所选应用服务器的部署描述符。 类似地,如果选择Axis作为工具箱,Tomcat作为服务器,也会生成特定于它们的文件。 | |
所有的Web service都是通过HTTP(或HTTPS)协议通信的。客户机发送SOAP(简单对象访问协议)请求,并等待SOAP响应。SOAP实质上是特殊格式的XML,用于描述通信。服务器和客户机都具有通过HTTP套接字通信的XML解析器和编码器。在接收到请求后,将其解码为可调用的、带参数的特定方法,在调用该方法后,其返回值会包装到XML-SOAP信封中并发回。
根据J2EE规范,Web应用程序必须使用特定的应用程序结构。WAR(Web ARchive)文件包含部署描述符和代码,并被压缩到EAR(Enterprise ARchive)文件中,以便最终安装在应用服务器上。因为该规范对于所有的平台都一视同仁,所以由任何工具箱开发的WAR和EAR程序包中的任何代码都可以在任意应用服务器上运行;但是,大部分应用服务器供应商的部署描述符文件多半不同。
令人欣慰的是,JBuilder简化了Web应用程序的开发,还可以经常使用独立的Axis Java2WSDL工具,也可以手动将代码打包到EAR文件中。
示例服务器
现在项目已经完成,可以将其部署到应用服务器上并作为Web service运行了。它应该是这样的(参见右边的面板): 用JBuilder部署Web service和创建它一样容易。确保BEA Weblogic正在运行。右击ApplicationModule1(服务应用程序模块名)并选择 -> Deploy Options -> Deploy。 | |
图7
JBuilder会显示如下内容:
Initiated Task: [0] [Deployer:149026]Deploy application ApplicationModule1 on myserver.Task 0 running: [Deployer:149026]Deploy application ApplicationModule1 on myserver.Deployment completed on Server myserver
就是这样!现在新的Web service已经驻留并可以被全世界使用了!
也可以解除部署,然后用同样的方法重新部署。所有当前的部署都可以在同一个菜单中列出。
要进行测试,可以打开JBuilder -> Tools-> Web Services Console,或者将Web浏览器指向http://localhost:7001/web-services/Bean1。
将会出现一个由Weblogic提供的、基于Web测试新服务的客户机,它会在后台调用SOAP通信来调用Bean1的方法。它甚至能够显示发送到各处的XML。
例如,单击getText()方法将会出现:
Parameter Name | Parameter Value |
Return Value | Hello |
向服务器发送请求:
服务器的响应:
Hello
向URL添加“?WSDL”可以看到整个WSDL文件:
http://localhost:7001/web-services/Bean1?WSDL
生产环境中的服务器部署当然不会使用JBuilder来部署EAR文件,而是使用与JBuilder同样易于操作的、基于Web的管理控制台,它通常和Weblogic服务器运行在同一端口上(例如:http://localhost:7001/console)。
请参阅有关如何使用其服务器管理功能的Weblogic文档;可以在JBuilder项目目录下找到ApplicationModule.EAR文件。
简单客户机
Weblogic测试客户机对业务不是很有用;其他客户机希望使用自己实现的Web service。创建客户机的一般机制是将Web service工具箱指向WSDL文件,并使它生成客户机对象存根。然后使用存根打开到服务器的端口,并调用其方法。存根也隐藏了对SOAP进行编组和解组的所有复杂性(都在后台处理)。但是,由于向项目添加了客户机模块,JBuilder会自动为项目添加一个GeneratedWebServicesClient文件夹,并创建Bean1_client.jar文件。
该jar文件包含了为Bean1服务添加全功能客户机所必需的所有文件。
以下是创建简单的测试客户机的步骤:
创建一个名为“test”的新程序包,并添加新的Test类。
然后,导入beanexport.generated.*程序包;由于该程序在项目中,所以它应该已经在类路径中了。
通过生成的存根来创建到该服务的连接:
String wsdlUrl = "http://localhost:7001/web-services/Bean1?WSDL";Bean1 service = new Bean1_Impl(wsdlUrl); //bind to serviceBean1Port port = service.getBean1Port(); //get port
然后任意调用一个方法。以下是完整的程序清单:
package test;import beanexport.generated.*;public class Test { public static void main(String[] args) { try { String wsdlUrl = "http://localhost:9501/web-services/Bean1?WSDL"; Bean1 service = new Bean1_Impl(wsdlUrl); Bean1Port port = service.getBean1Port(); int result = port.getInt(); System.out.println("Int is: " + result); Tuple[] tuple = port.getHeader(); System.out.println("1st tuple: " + tuple[0]); System.out.println("2nd tuple: " + tuple[1]); } catch (Exception e) { e.printStackTrace(); } }}
最终结果是一个可执行的程序,该程序使用Web service与服务器通信,调用之前还只是传统Java方法而现在是Web service的API。
结束语
本文介绍了Web service的基础知识。并创建了一个简单的Java类,将其转变为全功能的Web service。本文还讨论了如何生成与服务器通话并调用SOAP通信的客户机。
把“传统”代码打包为Web service主要涉及到对所使用工具的了解。当前的应用服务器和工具箱可以通过隐藏“信息管道”以及SOAP编组和XML解析的复杂性,使创建新的Web service或者将现有代码公开为Web service的任务变得很轻松。
清单1
Tuple Classpackage beanexport;import java.io.Serializable;public class Tuple implements Serializable { private String key; private String value; public Tuple() { } public Tuple(String key, String value) { this.key = key; this.value = value; } public Tuple(Object key, Object value) { this.key = key.toString(); this.value = value.toString(); } public String getValue() { return value; } public String getKey() { return key; this.key = key; } public void setValue(String value) { this.value = value; }} } public String toString() { return key + " : " + value; } public void setKey(String key) {
源代码
在此下载相关的源代码。