目前,大部分公司要么正在积极的开发Web service基础架构,要么正有此打算。老实说,利用以前写好的业务逻辑并将其作为Web service公开并不那么困难。在过去几年中,Web service标准获得了很大发展,如今已经变得可靠且健壮;甚至不同的开发工具箱也能够跨不同的平台生成标准的结果。
向业务流程添加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模块;采用所有默认值。
- 新建应用程序模块;同样采用所有默认值。

图4
- 在下一界面中,将服务器命名为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 |
向服务器发送请求:
<!--REQUEST.................-->
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<env:Body env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<m:getText xmlns:m="http://beanws">
</m:getText>
</env:Body>
</env:Envelope>
服务器的响应: <!--RESPONSE.................-->
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<env:Body env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<m:getTextResponse xmlns:m="http://beanws">
<result xsi:type="xsd:string">Hello</result>
</m:getTextResponse>
</env:Body>
</env:Envelope>
向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 service
Bean1Port 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 Class
package 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) {
源代码
在此下载相关的源代码。
在线参考资料和书籍
http://www.uddi.org/
统一描述、发现和集成(UDDI)协议是关系到能否成功构建Web services的重要因素。UDDI创建了一个标准的、可互操作的平台,使公司和应用程序能够轻松、快捷、动态地通过Internet找到并使用Web service。UDDI还允许出于不同的目的在不同的上下文中保留操作注册库。UDDI是整个行业努力的成果,各主要的平台和软件提供者、市场经营者、电子商务的领导者以及OASIS标准化协会都推动了它的发展。http://www.uddi.org/。
www.w3.org/TR/wsdl
WSDL是一种XML格式,它将网络服务描述为一组对消息进行操作的端点,这些消息中包含了面向文档或者是面向过程的信息。这些操作和消息是抽象描述的,然后再绑定到具体的网络协议和消息格式来定义端点。相关的具体端点会组合成抽象端点(服务)。WSDL具有可扩展性,它允许对端点及其消息的描述,而不考虑用于通信的是哪种消息格式或网络协议,然而,在该文档中描述了惟一的一个绑定,该绑定描述如何将WSDL与SOAP 1.1、HTTP GET/POST和MIME一起使用。
Borland软件公司
http://info.borland.com/techpubs/jbuilder/
使用JBuilder X Enterprise开发Web Services
使用JBuilder 2005 Enterprise开发Web Services
http://info.borland.com/techpubs/jbuilder/jbuilder2005/websvcs/contents.html
原文出处
http://www.developer.com/services/article.php/10928_3485321_1
作者简介 |
|
Vlad Kofman是一名系统架构师,他致力于政府防御合同相关的项目。他还参与了许多华尔街主要公司和美国政府的企业级项目。他的主要兴趣是面向对象编程方法和设计模式。 |