IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope:Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  SOA and Web services | WebSphere  >

基于WAS CE和Axis2开发Web Service应用

developerWorks
文档选项

未显示需要 JavaScript 的文档选项

样例代码


级别: 中级

孟 嘉 (mengjia.1982@gmail.com), 北京大学软件工程研究所,硕士
张 松 (scorpio.song@gmail.com), IBM中国软件开发中心 软件工程师

2006 年 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中创建数据库及表
图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 输入数据源模块的名字和数据连接的类型
图2 输入数据源模块的名字和数据连接的类型

第二步输入数据源的属性,包括数据源名、数据源所对应的真实数据库名、数据库用户名及密码、最大最小连接数等。我们这里的数据源起名为"jdbc/AXIS2Datasource",使用内建的Derby数据库,数据库为我们刚才创建的Axis2,用户名密码可以省略。对于其它属性,可以使用默认值(如不填写,wizard则使用默认值)。如图3所示,然后点击Deploy按钮。


图3 输入数据源的属性
图3 输入数据源的属性

可以看到,我们为Axis2创建的数据源已经成功的部署到WAS CE上去,如图4所示。可以通过edit链接对数据源的属性进行修改。


图4 成功部署数据源
图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欢迎和环境验证页面
图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文件内容
图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 成功部署网上花店服务页面
图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文件。






回页首


下载

名字大小下载方法
flowershop.zip15KBHTTP
关于下载方法的信息


参考资料

学习

获得产品和技术


作者简介

孟嘉是北京大学软件工程研究所的硕士研究生,从事J2EE应用服务器的研究与开发。他对开源项目有很大兴趣,有3年以上的Java与J2EE开发经验。他的电子邮箱是mengjia.1982@gmail.com


张松是IBM中国软件开发中心的软件工程师,所在团队目前从事WebSphere Application Server Community Edition产品相关的开发测试、售后服务和客户技术支持等工作。他的电子邮箱是scorpio.song@gmail.com




对本文的评价

太差! (1)
需提高 (2)
一般;尚可 (3)
好文章 (4)
真棒!(5)

建议?




回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款