本文将介绍如何使用WAS CE(WebSphere Application Server Community Edition)和Apache Axis2开发、部署及测试一个简单的Web Service应用-网上花店。
引言
近
年来,随着Web Service技术迅速发展,基于Web Service开发的应用被使用的越来越广泛。Web
Service良好的封装性及跨平台能力为应用程序集成、B2B集成等应用场景提供可行的解决方案。本文将介绍如何使用WAS
CE(WebSphere Application Server Community Edition)和Apache
Axis2开发、部署及测试一个简单的Web Service应用-网上花店。
1.应用及运行环境介绍
1.1 WAS CE简介
WebSphere Application Server Community Edition是IBM推出的基于开源项目Apache
Geronimo技术构建的轻量级J2EE应用服务器,是WebSphere Application Server产品家族的新成员。它符合Java
2 Enterprise Edition (J2EE) V1.4规范,像所有J2EE应用服务器一样,它为运行多层次的企业级应用程序提供平台。
本文中将介绍一个Web Service应用示例-网上花店的开发、部署、测试过程。WAS CE为网上花店服务所使用的SOAP引擎
Axis2提供Web容器,并提供其内建的Derby数据库用于数据存取。在本文中的示例中,使用WAS CE
v1.0.1.2版本,但在示例代码下载中同样提供针对Apache
GeronimoV1.1版本的Derby数据源和Axis2的部署计划。读者可以根据使用的服务器选择不同的部署计划。
1.2 Axis2简介
Apache Axis2 是Axis的后续版本,是新一代的SOAP引擎。
Axis2的主要特点有:
采用名为 AXIOM(AXIs Object Model)的新核心 XML 处理模型,利用新的XML解析器提供的灵活性按需构造对象模型 支持不同的消息交换模式。目前Axis2支持三种模式:In-Only、Robust-In和In-Out。In-Only消息交换模式只有SOAP请求,而不需要应答; Robust-In消息交换模式发送SOAP请求,只有在出错的情况下才返回应答;In-Out消息交换模式总是存在SOAP请求和应答。 提供阻塞和非阻塞客户端 API 支持内置的 Web服务寻址 (WS-Addressing) 灵活的数据绑定,可以选择直接使用 AXIOM,使用与原来的 Axis 相似的简单数据绑定方法,或使用 XMLBeans、JiBX 或 JAXB 2.0 等专用数据绑定框架 新的部署模型,支持热部署 支持HTTP,SMTP,JMS,TCP传输协议 支持REST (Representational State Transfer)
Axis2 支持的规范包括:
SOAP 1.1 and 1.2 Message Transmission Optimization Mechanism (MTOM), XML Optimized Packaging (XOP) and SOAP with Attachments WSDL 1.1, including both SOAP and HTTP bindings WS-Addressing (submission and final) WS-Policy SAAJ 1.1
有关Axis2更加详细的介绍,可以访问Axis2网站http://ws.apache.org/axis2/ 。
1.3 网上花店简介
网上花店是基于Web Service的应用,它为用户提供了留言、查询及预定三类服务:
留言:给网上花店留言,服务器接收到留言消息并处理后,不发出返回消息。使用In-Only消息交换模式。 查询:服务器根据花的编号在数据库中查询,返回花的信息。使用In-Out消息交换模式。 预定:服务器根据花的编号进行预定,返回预定成功或预定失败消息。允许客户端发出预定消息后可以继续执行下面代码,不必等待消息返回。使用In-Out消息交换模式。 2.在WAS CE上部署Axis2
如
果基于Axis2开发的Web Service不需要使用WAS
CE提供的额外服务,可以从http://ws.apache.org/axis2/download.cgi 下载Axis2
的WAR格式分发包(axis2.war),然后将它直接部署到WAS
CE上。部署Axis2分发包可以通过管理控制台中的"Application->Deploy New"操作,也直接将axis2.war
复制到%WASCE_HOME%/deploy目录中。更加详细的部署过程,请查看参考资料。
由于网上花店需要使用WAS CE提供的内建数据库,所以需要在部署Axis2之前为其部署数据源,使得Axis2中的服务可以方便的使用到WAS CE数据库。
首先我们在WAS CE中为Axis2创建数据库,并为网上花店服务创建Flower表。创建数据库和表可以使用WAS
CE管理控制台,或者使用WAS CE提供的ij工具。这里介绍通过管理控制台实现创建操作。进入WAS
CE管理控制台(默认用户名为system,密码为manager),在左边的导航栏中选择"Embedded DB -〉DB
Manager",在Create
DB后面的输入栏里面输入"Axis2",按下Create按钮,这样就创建了一个名为Axis2的数据库。确保Use
DB后面选择的是我们刚刚创建的名Axis2的数据库,然后在SQL
Command/s输入区里面输入创建Flower表的SQL语句(如下),按下Run SQL按钮,这样Flower表也创建完成了。
CREATE TABLE FLOWER ( ID INTEGER NOT NULL PRIMARY KEY, NAME VARCHAR(20), DESCRI VARCHAR(100), PRICE DOUBLE ); INSERT INTO FLOWER VALUES (1,'Rose','a kind of beatiful flowers',10); INSERT INTO FLOWER VALUES (2,'Lily','a kind of beatiful flowers',20);
在View DB页面查看,可以看到Flower中的内容,如图1所示:
图1 在WAS CE中创建数据库及表
创建好数据库后,便可以为Axis2部署数据源,并将此数据源指向Derby中的名为Axis2的数据库,即我们刚刚创建的数据库。
为Axis2部署数据源可以通过WAS CE管理控制台提供的database pool wizard工具,也可以通过编写部署计划实现。下面将分别介绍这两种方法:
1.通过database pool wizard部署数据源
进入管理工具,在左侧的导航栏里面选择"Services->Database Pools",在Database Pools页面里面选择"Using the Geronimo database pool wizard"链接,创建一个新的数据源。
第一步需要给出数据源模块的名字和数据连接的类型。在Name of Database Pool 输入框里面输入AXIS2Datasource,在Database Type单选框里面选择Derby embedded XA,如图2 所示,然后点击Next按钮。
图2 输入数据源模块的名字和数据连接的类型
第二步输入数据源的属性,包括数据源名、数据源所对应的真实数据库名、数据库用户名及密码、最大最小连接数等。我们这里的数据源起名为
"jdbc/AXIS2Datasource",使用内建的Derby数据库,数据库为我们刚才创建的Axis2,用户名密码可以省略。对于其它属性,可
以使用默认值(如不填写,wizard则使用默认值)。如图3所示,然后点击Deploy按钮。
图3 输入数据源的属性
可以看到,我们为Axis2创建的数据源已经成功的部署到WAS CE上去,如图4所示。可以通过edit链接对数据源的属性进行修改。
图4 成功部署数据源
2.通过编写部署计划部署数据源
我们也可以选择通过编写部署计划部署数据源。这种方法更加灵活。部署之前,我们先要编写部署数据源的计划,如下:
<?xml version="1.0" encoding="UTF-8"?> <connector xmlns="http://geronimo.apache.org/xml/ns/j2ee/connector-1.0" configId="AXIS2Datasource" parentId="geronimo/j2ee-server/1.0/car"> <resourceadapter> <outbound-resourceadapter> <connection-definition> <connectionfactory-interface>javax.sql.DataSource </connectionfactory-interface> <connectiondefinition-instance> <name>jdbc/AXIS2Datasource</name> <config-property-setting name="UserName"></config-property-setting> <config-property-setting name="Password"></config-property-setting> <config-property-setting name="DatabaseName">Axis2</config-property-setting> <config-property-setting name="CreateDatabase">true</config-property-setting> <connectionmanager> <xa-transaction> <transaction-caching/> </xa-transaction> <single-pool> <max-size>5</max-size> <min-size>0</min-size> <blocking-timeout-milliseconds>5000 </blocking-timeout-milliseconds> <idle-timeout-minutes>15</idle-timeout-minutes> <match-one/> </single-pool> </connectionmanager> </connectiondefinition-instance> </connection-definition> </outbound-resourceadapter> </resourceadapter> </connector>
在上面的部署计划中:configId="AXIS2Datasource" 定义了数据源模块的标识名;<name>jdbc/AXIS2Datasource</name>定义了数据源的名字,它指向名为Axis2的数据库。
编
写好数据源部署计划后,我们需要将其部署到WAS CE上。因为我们使用WAS CE内建的数据库Derby,所以部署的应用包实际为Derby
xa文件,在WAS CE
v1.0版本中,它存放为%WASCE_HOME%/repository/tranql/rars/tranql-connector-derby-
embed-xa-1.1.rar。我们可以使用管理控制台中的"Applications->Deploy
New"部署数据源,也可以使用以下命令行:deploy.[bat|sh] --user system --password manager
deploy axis2-ds-plan.xml
%WASCE_HOME%/repository/tranql/rars/tranql-connector-derby-embed-xa-1.1.rar
数据源部署成功后,通过管理控制台"Applications->J2EE Connectors"可以查看到我们刚刚部署的数据源模块wasce-db/AXIS2Datasource/1.1/rar已经被启动。
下一步,我们将Axis2部署到WAS CE上。由于我们发布到Axis2上的网上花店服务需要使用WAS CE提供的数据源jdbc/AXIS2Datasource,我们在部署Axis2之前,还需要修改Axis2的部署计划。
本文中使用Axis2 v1.0 (可以从http://ws.apache.org/axis2/download.cgi 下载Axis2
WAR格式分发包axis2.war)。首先,我们在axis2.war中的WEB-INF目录中添加geronimo_web.xml文件(此目录中已
经存在web.xml文件),
用于定义Axis2的模块信息及对数据源使用。geronimo_web.xml文件内容如下(注意,如果使用Apache Geronimo
v1.1,该文件格式不同):
<?xml version="1.0" encoding="UTF-8"?> <web-app configId="org/apache/axis2" xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-1.0" xmlns:naming="http://geronimo.apache.org/xml/ns/naming-1.0" xmlns:sec="http://geronimo.apache.org/xml/ns/security-1.0" xmlns:sys="http://geronimo.apache.org/xml/ns/deployment-1.0" > <context-root>/axis2</context-root> <context-priority-classloader>false</context-priority-classloader> <naming:resource-ref> <naming:ref-name>jdbc/DataSource</naming:ref-name> <naming:resource-link>jdbc/AXIS2Datasource</naming:resource-link> </naming:resource-ref> </web-app>
另外,我们还需要web.xml文件中加入对数据源的引用:
<web-app> …… <resource-ref> <res-ref-name>jdbc/DataSource</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> <res-sharing-scope>Shareable</res-sharing-scope> </resource-ref> </web-app>
然后我们便可以将修改后的axis2.war部署到WAS CE中。仍可以通过管理控制台"Applications->Deploy
New"完成部署。由于我们已经将部署计划的内容写在了geronimo_web.xml文件里面,故部署axis2.war时,就不需要提供额外的部署
文件了。也可以通过命令行"deploy.[bat|sh] --user system --password manager deploy
axis2.war"完成部署。
至此,我们完成了在WAS CE上部署Axis2的工作。访问 http://localhost:8080/axis2将显示 Axis2 欢迎页,单击此页上的 Validate 链接,将到达 Axis2 Happiness Page,如图5所示。
图5 Axis2欢迎和环境验证页面
3.编写网上花店服务实现类及服务部署文件
下面我们将开始开发网上花店服务的业务逻辑。基于Axis2开发Web
Service一般采用两种方法:第一种方法直接实现业务逻辑,它通常包括提供服务实现类 (implementation
class)、编写服务描述文件services.xml、将服务实现类和描述文件打成aar (Axis ARchive)
包、部署服务四个步骤;第二种方法使用WSDL2Java Tool工具,通过WSDL生成代码框架( Skeleton)
,然后再在框架中填写业务逻辑。两种方法的具体的过程可以参考Axis2用户手册。本文将采用第一种方法开发网上花店服务。
第
一步,我们来开发网上花店的服务实现类FlowerService.java。它包括三个方法,分别对应前面介绍的留言、查询、预定三个服务。留言服务采
用In-Only消息交换模式,而查询和预定两个服务采用In-Out消息交换模式,这就意味着客户端使用留言服务时,服务器端是不会向客户端发出返回消
息的,而对于其它两个服务客户端在发出消息后会收到服务器端的回复。下面是FlowerService的实现代码:
package example.flowershop; import java.sql.*; import javax.naming.*; import javax.sql.DataSource; import javax.xml.namespace.QName; import org.apache.axiom.om.*; public class FlowerService { public void message(OMElement in) { String message = in.getText(); System.out.println("FlowerShop received message: " + message); //deal with the message here } public OMElement query(OMElement in) { … } public OMElement reserve(OMElement in){ … } }
以上的代码给出了message方法的实现,读者可能注意
到FlowerService中三个方法的参数都是OMElement。OMElement是AXIOM (AXIs Object
Model)实现的部分,可以看作OMElement封装了一段XML信息。AXIOM XML
解析器允许按需构造对象模型,大大提高了Axis2的效率。采用AXIOM的新核心 XML 处理模型也是Axis2的最大特点之一。
关于AXIOM的使用,可以浏览参考资料AXIOM Tutorial,本文将不作过多解释。
下面我们来重点看一下query方法的实现:
public OMElement query(OMElement in){ int flowerid = Integer.parseInt(in.getText()); String info = "Can not query!"; try { //use axis2 datasource we deployed before Context initContext = new InitialContext(); Context envContext = (Context)initContext.lookup("java:/comp/env"); DataSource ds = (DataSource)envContext.lookup("jdbc/DataSource"); Connection con = ds.getConnection(); Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery( "SELECT * FROM FLOWER WHERE ID=" + flowerid ); while (rs.next()) { info = "ID=" + rs.getInt("ID") + " NAME=" + rs.getString("NAME") + " DESCRIPTION=" + rs.getString("DESCRI") + " PRICE=" + rs.getDouble("PRICE"); } } catch(Exception e) { } //create the OMElement for response OMFactory fac = OMAbstractFactory.getOMFactory(); OMNamespace omNs = fac.createOMNamespace("http://flowershop.com/", "flower"); OMElement resp = fac.createOMElement("getFlowerInfo", omNs); resp.setText(info); return resp; }
在query方法的业务逻辑中,我们首先解析请求消
息,从请求消息中获取需要查询的花的ID;随后通过ID在数据源中查询花的详细信息。我们使用jdbc/DataSource数据源引用,它通过
jdbc/AXIS2Datasource指向WAS CE内嵌的Derby中名为Axis2的具体数据库。数据源是我们在向WAS
CE中部署Axis2时已经设置好的。当服务需要使用数据源时,只需在业务逻辑代码中使用JNDI的方式将其查找出来即可。最后,我们依据查找出来的信息
生成返回消息。和query方法类似的过程,reserve方法实现如下:
public OMElement reserve(OMElement in) { String flowerid = (in.getFirstChildWithName(new QName("flowerid"))).getText(); String num = (in.getFirstChildWithName(new QName("flowernum"))).getText(); String address = (in.getFirstChildWithName(new QName("address"))).getText(); System.out.println("Please send " + num + " flowers(id=" + flowerid + ") to " + address + "!"); String message = "Reserve Failed:"; //do the reservation here and set response message OMFactory fac = OMAbstractFactory.getOMFactory(); OMNamespace omNs = fac.createOMNamespace("http://flowershop.com/", "flower"); OMElement resp = fac.createOMElement("reserveResponse", omNs); resp.setText(message + "ID=" + flowerid + " NUM=" +num); return resp; }
在 Axis2 中,服务部署信息包含在
services.xml 文件(在 0.92 以前的版本中,此文件名为
service.xml)中,它的作用相当于EJB应用中的部署描述符文件(如ejb-jar.xml)。部署之前,我们需要提供此文件。下面我们来看一
下services.xml 文件到底包括了哪些部署描述信息:
图6 services.xml文件内容
服务名和服务实现类的定义是必不可少的,对于服务实现类中的每一个方法,需要指定一个消息接收器。Axis2 针对
In-Only 和 In-Out 消息交换模式提供了两个内置消息接收器:用于 In-Only
操作的org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver和用于In-Out
操作org.apache.axis2.receivers.RawXMLINOutMessageReceiver。如果一个方法没有指定消息接收器,
则 Axis2 将尝试使用 org.apache.axis2.receivers.RawXMLINOutMessageReceiver
作为缺省的接收器。本文例子中的方法就是使用以上介绍的Axis2提供的内置消息接收器。这些RawXML消息接收器将传入SOAP 消息中的
<Body> 元素作为
OMElement传递给服务实现类中的方法。同样的,当方法返回OMElement时,其内容将被转换为SOAP 消息中的<Body>
元素返回。
也可以在services.xml中描述一组服务,这样可以方便地部署与管理一组相关的服务,并且在运行时可以通过ServiceGroupContext在这组服务的内部传递信息。
4.在Axis2上部署网上花店服务
编写好业务逻辑及服务描述文件后,下一步我们将它们按规定结构打成Axis2可部署包,然后部署。Axis2使用aar (Axis ARchive)文件作为服务的部署单元。我们将网上花店打成FlowerService.aar,对应结构为:
|- example | |- flowershop | |- FlowerService.class |- META-INF | |- services.xml
打包生成aar文件时,可以先将相应文件按结构复制到一个临时目录temp,然后进入到temp目录,运行:
jar cvf FlowerService.aar .
部署aar文件非常简单,只需将aar文件复制到
Axis2应用中的WEB-INF/services目录下即可(若使用WAS CEv1.0,
此位置为%WASCE_HOME%/config-store/XX/war/WEB-INF/services,其中XX是一个数字,可以在%
WASCE_HOME%/config-store/index.properties里面查到Axis2应用所对用的数字;若使用Geronimo
v1.1,此位置为%GERONIMO_HOME%/repository/apache/Axis2/2.0/Axis2-2.0.war/WEB-
INF/services)。另一种方法是通过Axis2 管理控制台中的"Tools -> Upload
Service"工具来部署服务。在http://localhost:8080/axis2页面选择 Administration
链接。输入默认的用户名admin和密码axis2登录(用户名密码可以在 axis2.xml 中配置)。在左侧导航栏中的Tools部分选择
Upload Service 链接,再在本地文件系统中选择要部署的aar文件,然后单击Upload。这样就完成了部署。向远程 Axis2
服务器上部署服务,这种方法非常方便。如果上传成功,Axis2管理控制台将显示成功消息,如:"File FlowerService.aar
successfully uploaded",同时服务也已经被启动。部署成功后,可在Axis2管理控制台中的"System
Components -> Available
Services"查看到已部署的服务。图7显示了我们已经部署成功的FlowerService的信息:
图7 成功部署网上花店服务页面
5.编写客户端,测试
下面我们来测试一下网上花店服务。可以使用Axis2提供的客户端接口实现对服务的调用,客户端的调用方法封装在ServiceClient类中。Axis2提供了阻塞和非阻塞客户端 API,对于本文的例子,我们可以采用以下三种方式调用服务:
1.调用In-Only服务
对于 In-Only服务,服务器端将不返回消息,使用ServiceClient.fireAndForget(OMElement)方法进行调用。测试网上花店留言服务的代码如下:
package example.client; import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMFactory; import org.apache.axiom.om.OMNamespace; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.Options; import org.apache.axis2.client.ServiceClient; public class TestMessage { private static EndpointReference targetEPR = new EndpointReference( "http://localhost:8080/axis2/services/FlowerService"); public static OMElement getMessageOMElement() { OMFactory fac = OMAbstractFactory.getOMFactory(); OMNamespace omNs = fac.createOMNamespace("http://flowershop.com/", "flower"); OMElement method = fac.createOMElement("message", omNs); method.setText("Your roses are good!"); return method; } public static void main(String[] args) { try { // Make the request message Options options = new Options(); options.setTo(targetEPR); ServiceClient sender = new ServiceClient(); sender.setOptions(options); // test message method OMElement message = TestMessage.getMessageOMElement(); sender.fireAndForget(message); Thread.sleep(500); } catch (Exception axisFault) { axisFault.printStackTrace(); } } }
2.使用阻塞API调用In-Out服务
阻塞API在客户端发出消息的时候,等待消息返回才继续执行下面的代码。使用ServiceClient.sendReceive(OMElement)方法进行调用。测试网上花店查询服务的代码如下:
package example.client; import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMFactory; import org.apache.axiom.om.OMNamespace; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.Options; import org.apache.axis2.client.ServiceClient; public class TestQuery { private static EndpointReference targetEPR = new EndpointReference( "http://localhost:8080/axis2/services/FlowerService"); public static OMElement getQueryOMElement() { OMFactory fac = OMAbstractFactory.getOMFactory(); OMNamespace omNs = fac.createOMNamespace("http://flowershop.com/", "flower"); OMElement method = fac.createOMElement("query", omNs); method.setText("1"); return method; } public static void main(String[] args) { try { // Make the request message Options options = new Options(); options.setTo(targetEPR); ServiceClient sender = new ServiceClient(); sender.setOptions(options); // test query method OMElement query = TestQuery.getQueryOMElement(); OMElement result = sender.sendReceive(query); System.out.println(result); } catch (Exception axisFault) { axisFault.printStackTrace(); } } }
3.使用非阻塞API调用In-Out服务
非阻塞API在客户端发出消息的时候后不等待消息返回就继续执
行下面的代码。返回消息的处理在回调函数中进行。使用非阻塞的调用,需要在调用之前设置回调函数。使用
ServiceClient.sendReceiveNonBlocking (OMElement,
Callback)方法进行调用。测试网上花店预定服务的代码如下:
package example.client; import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMFactory; import org.apache.axiom.om.OMNamespace; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.Options; import org.apache.axis2.client.ServiceClient; import org.apache.axis2.client.async.AsyncResult; import org.apache.axis2.client.async.Callback; public class TestReserve { private static EndpointReference targetEPR = new EndpointReference( "http://localhost:8080/axis2/services/FlowerService"); public static OMElement getReserveOMElement() { OMFactory fac = OMAbstractFactory.getOMFactory(); OMNamespace omNs = fac.createOMNamespace("http://flowershop.com/", "flower"); OMElement method = fac.createOMElement("reserve", omNs); OMElement id = fac.createOMElement("flowerid", omNs); id.setText("1"); method.addChild(id); OMElement num = fac.createOMElement("flowernum", omNs); num.setText("99"); method.addChild(num); OMElement address = fac.createOMElement("address", omNs); address.setText("IBM "); method.addChild(address); return method; } public static void main(String[] args) { try { // Make the request message Options options = new Options(); options.setTo(targetEPR); ServiceClient sender = new ServiceClient(); sender.setOptions(options); // test reserve method using non-Blocking API // Callback to handle the response OMElement reserve = TestReserve.getReserveOMElement(); Callback callback = new Callback() { public void onComplete(AsyncResult result) { System.out.println("From Callback Function:" + result.getResponseEnvelope()); } public void onError(Exception e) { e.printStackTrace(); } }; sender.sendReceiveNonBlocking(reserve, callback); // Wait till the callback receives the response. while (!callback.isComplete()) { Thread.sleep(1000); } } catch (Exception axisFault) { axisFault.printStackTrace(); } } }
最后,我们通过依次运行客户端代码来测试一下网上花店服务。测试结果WAS CE的控制台将会显示:
FlowerShop received message: Your roses are good! Please send 99 flowers(id=1) to IBM !
而客户端控制台将会显示:
<flower:getFlowerInfo xmlns:flower="http://flowershop.com/" xmlns:tns="http://ws.apache.org/axis2">ID=1 NAME=Rose DESCRIPTION=a kind of beatiful flowers PRICE=10.0</flower:getFlowerInfo> From Callback Function:<?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header /><soapenv:Body> <flower:reserveResponse xmlns:flower="http://flowershop.com/" xmlns:tns="http://ws.apache.org/axis2">Reserve Successful:ID=1 NUM=99 </flower:reserveResponse> </soapenv:Body> </soapenv:Envelope>
6.结束语
本
文通过一个Web Service应用示例-网上花店,介绍了基于WAS CE和Axis2的Web
Service应用的开发、部署、测试过程。在开发过程中,本文采用了直接实现业务逻辑的方法。读者也可以尝试一下通过WSDL生成代码框架,然后在框架
中填写业务逻辑的方法来实现Web Service应用,在本文的示例代码下载的wsdl目录中已经提供了网上花店服务的WSDL文件。
参考资料
学习 获得产品和技术 作者简介
张松是IBM中国软件开发中心的软件工程师,所在团队目前从事WebSphere Application Server Community Edition产品相关的开发测试、售后服务和客户技术支持等工作。他的电子邮箱是scorpio.song@gmail.com 。