006 年 10 月 16 日
本文将介绍如何使用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(); } } }
|
![](https://i-blog.csdnimg.cn/blog_migrate/05ac63f463130bd1876c1af927ae88a3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/c6ccbc96c20bebb0d73e8e6368158ef5.gif) |
![](https://i-blog.csdnimg.cn/blog_migrate/c6ccbc96c20bebb0d73e8e6368158ef5.gif)
|
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文件。