原文链接:http://ws.apache.org/axis2/1_1_1/quickstartguide.html 
本指南的目的是让你尽可能快的创建使用Axis2的服务和客户端,我们将使用一个简单的StockQuote服务并显示给你一些创建和部署它 
的不同的方式,以及快速的看看Axis2自带的一些工具,然后我们将看看创建访问这些服务的客户端。 
内容 
    - 介绍   
- 做好准备   
- <SPAN class=hilite1>Axis2</SPAN>服务   
- 创建服务   
-     部署POJOs   
-     使用AXIOM构建服务   
-     使用ADB生成服务   
-     使用XMLBeans生成服务   
-     使用JiBX生成服务   
- 生成客户端   
-     使用AXIOM创建一个客户端   
-     使用ADB生成一个客户端   
-     使用XMLBeans生成一个客户端   
-     使用JiBX生成一个客户端   
- 总结   
- 进一步学习  
 
介绍
做好准备
Axis2服务
创建服务
部署POJOs
使用AXIOM构建服务
使用ADB生成服务
使用XMLBeans生成服务
使用JiBX生成服务
生成客户端
使用AXIOM创建一个客户端
使用ADB生成一个客户端
使用XMLBeans生成一个客户端
使用JiBX生成一个客户端
总结
进一步学习
快速安装笔记: 
文档的代码可以在解压的标准二进制发布[/url]找到,更明确的位于其中的Axis2_HOME/samples/目录-quickstart,quickstartdb, 
quickstartaxiom,quickstartjibx和quickstartxmlbeans,如果你继续下去它将帮你掌握它。它包含一个Ant构建文件(build.xml) 
贯穿所有的例子我们将提到它来使得编译更容易。 
介绍 
让我们以服务本身开始。我们将使它简单,所以你可以看到当我们构建并部署服务时会发生什么,一个StockQuoteService例子看起来 
像这个,所以让我们使用下面的(参看Code Listing 1)。 
Code Listing 1: StockQuoteService类 
    - package samples.quickstart.service.pojo;   
-   
- import java.util.HashMap;   
-   
- public class StockQuoteService {   
-     private HashMap map = new HashMap();   
-   
-     public double getPrice(String symbol) {   
-         Double price = (Double) map.get(symbol);   
-         if(price != null){   
-             return price.doubleValue();   
-         }   
-         return 42.00;   
-     }   
-   
-     public void update(String symbol, double price) {   
-         map.put(symbol, new Double(price));   
-     }   
- }  
 
package samples.quickstart.service.pojo;
import java.util.HashMap;
public class StockQuoteService {
private HashMap map = new HashMap();
public double getPrice(String symbol) {
Double price = (Double) map.get(symbol);
if(price != null){
return price.doubleValue();
}
return 42.00;
}
public void update(String symbol, double price) {
map.put(symbol, new Double(price));
}
}
它将为一个具有两个可能的调用的简单服务,其中一个是一个in/out消息,另一个则为一个只能in的服务,最终我们将打包服务并用 
四种不同的方式部署部署它。 
首先,让我们看看这个简单的Java类怎样响应一个服务。 
做好准备 
在我们使用Axis2构建任何东西之前,我们将需要关注一些家务事。现在你将需要准备好你使用Axis2的环境,幸运的是,它只包括一 
些简单的步骤: 
1,下载并安装Java(版本至少为JDK1.4) 
2,下载Axis2并解压到一个目标目录 
3,复制axis2.war文件到你的servlet引擎的webapps目录 
4,设置AXIS2_HOME环境变量来指出目标目录,注意Axis2生成的所有脚本和构建文件依赖于这个值,所以不要遗漏了这个步骤。 
大多数情况下,我们的服务也将需要一个WSDL文件,Axis2的Java2WSDL可以用来生成一个WSDL。执行以下步骤来从一个Java类生成一 
个WSDL文件: 
1,创建并编译Java类 
2,使用该命令生成WSDL: 
%AXIS2_HOME%/bin/java2wsdl -cp . -cn samples.quickstart.service.pojo.StockQuoteService -of StockQuoteService.wsdl 
移动你生成WSDL文件,你可以做你需要的任何更改。例如,你可能添加自定义的过错或者改变生成的元素名。例如,该StockQuoteSer 
vice.wsdl位于%AXIS2_HOME%/samples/quickstartadb/resources/META-INF文件夹,我们将在本指南的其他部分使用它,代替生成过 
程创建的一般参数。 
Axis2服务 
在我们构建任何东西之前,理解最终产品看起来像什么是有用的。Axis2的服务器端可以被部署在任何Servlet引擎上,并且有如下的 
Code Listing 2显示的结构。 
Code Listing 2: axis2.war的目录结构 
    - <SPAN class=hilite1>axis2</SPAN>-web    
- META-INF   
- WEB-INF   
-     classes    
-     conf   
-         <SPAN class=hilite1>axis2</SPAN>.xml    
-     lib   
-         activation.jar   
-         ...   
-         xmlSchema.jar   
-     modules   
-         modules.list    
-         addressing.mar   
-         ...   
-         soapmonitor.mar   
-     services   
-         services.list   
-         aservice.aar   
-         ...   
-         version.aar   
-     web.xml  
 
axis2-web
META-INF
WEB-INF
classes
conf
axis2.xml
lib
activation.jar
...
xmlSchema.jar
modules
modules.list
addressing.mar
...
soapmonitor.mar
services
services.list
aservice.aar
...
version.aar
web.xml
从最上面开始,axis2-web是组成Axis2管理程序的一些JSPs,你可以通过它来执行任何需要的动作,例如添加服务,使用模块和禁止 
模块。WEB-INF包含了运行部署到服务目录的任何服务的实际上的java类和其他支持文件。 
这里主要的文件是axis2.xml,它控制程序怎样与接收的消息打交道,决定Axis2是否需要使用模块目录里定义的任何模块。 
这里你可以看到,服务可以被部署为*.aar文件,但是它们的内容必须以一个特殊的方式安排。例如,服务的结构将为如下: 
    - - StockQuoteService   
-    - META-INF   
-      - services.xml   
-    - samples   
-      - quickstart   
-        - service   
-          - pojo   
-            - StockQuoteService.class  
 
- StockQuoteService
- META-INF
- services.xml
- samples
- quickstart
- service
- pojo
- StockQuoteService.class
这不是太复杂,服务的名字为StockQuoteService,它在services.xml中指定,并且根据包名把任何Java类放到合适的位置。META-INF 
目录包含关于Axis2需要来正确执行服务的额外信息。services.xml文件定义了服务本身并把Java类链接到它(参看Code Listing 3)。 
Code Listing 3: 服务定义文件 
    - <service name="StockQuoteService" scope="application">   
-     <description>   
-         Stock Quote Sample Service   
-     </description>   
-     <messageReceivers>   
-         <messageReceiver    
-             mep="http://www.w3.org/2004/08/wsdl/in-only"  
-     class="org.apache.<SPAN class=hilite1>axis2</SPAN>.rpc.receivers.RPCInOnlyMessageReceiver"/>   
-         <messageReceiver   
-             mep="http://www.w3.org/2004/08/wsdl/in-out"  
-     class="org.apache.<SPAN class=hilite1>axis2</SPAN>.rpc.receivers.RPCMessageReceiver"/>   
-     </messageReceivers>   
-     <parameter name="ServiceClass">   
-         samples.quickstart.service.pojo.StockQuoteService   
-     </parameter>   
- </service>  
 
<service name="StockQuoteService" scope="application">
<description>
Stock Quote Sample Service
</description>
<messageReceivers>
<messageReceiver
mep="http://www.w3.org/2004/08/wsdl/in-only"
class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
<messageReceiver
mep="http://www.w3.org/2004/08/wsdl/in-out"
class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
</messageReceivers>
<parameter name="ServiceClass">
samples.quickstart.service.pojo.StockQuoteService
</parameter>
</service>
这里你看到服务本身被定义了,以及不同的消息交换模式相关的messageReceiver类型。 
META-INF目录也是你打算包含在该程序中的自定义WSDL文件的位置。 
你可以通过简单的采用该文件目录结构并复制到你的servlet引擎的webapps目录来部署一个服务,这是著名的"爆发"形式,但是你也 
可以压缩你的文档到一个*.aar文件,类似于一个*.jar文件,并直接将*.aar文件放到servlet引擎的webapps目录。 
既然你理解了我们在尝试完成什么,我们几乎准备好开始构建了。 
首先,下载并解压合适版本的Axis2标准二进制发布。确认你设置了AXIS2_HOME变量的值来匹配你解压该版本内容的位置。 
让我们看看一些创建客户端和服务的不同方式。 
创建服务 
在这个部分,我们将看看根据StockQuoteService类创建服务的五种方式:部署Plain Old Java Objects(POJO),使用AXIOM的OMElement 
构建服务,使用Axis2 Databinding Framework(ADB)生成服务,使用XMLBeans生成服务和使用JiBX生成服务。 
部署POJOs 
使用POJOs(Plain Old Java Objects)来部署服务,执行下面的步骤。 
注意包含在<AXIS2_HOME>/samples/quickstart的目录结构(services.xml文件来自于该指南的第一个部分): 
    - - quickstart   
-    - README.txt   
-    - build.xml   
-    - resources   
-      - META-INF   
-        - services.xml   
-    - src   
-      - samples   
-        - quickstart   
-          - service   
-            - pojo   
-              - StockQuoteService.java  
 
- quickstart
- README.txt
- build.xml
- resources
- META-INF
- services.xml
- src
- samples
- quickstart
- service
- pojo
- StockQuoteService.java
注意你可以通过在quickstart目录键入ant generate.wsdl来生成WSDL。 
尽管如此,创建StockQuoteService.wsdl是可选的。它可以是直接从Java类生成的版本,或者该文件的一个自定义版本,并且servi 
ces.xml是本文档前面提到的同一文件。 
现在通过在quickstart目录键入ant generate.service来构建工程,该目录创建了以下目录结构: 
    - - quickstart/build/classes   
-    - META-INF   
-      - services.xml   
-    - samples   
-      - quickstart   
-        - service   
-          - pojo   
-            - StockQuoteService.class  
 
- quickstart/build/classes
- META-INF
- services.xml
- samples
- quickstart
- service
- pojo
- StockQuoteService.class
如果你想以爆发形式部署服务,重命名classes目录为StockQuoteService,并复制它到你的servlet引擎的webapps/axis2/WEB-INF/s 
ervices目录。否则,复制build/StockQuoteService.aar文件到你的servlet引擎的webapps/axis2/WEB-INF/services目录。然后通过 
视察以下服务列表来确认服务被正确部署: 
http://localhost:8080/axis2/services/listServices 
你也可以检验以下WSDL: 
http://localhost:8080/axis2/services/StockQuoteService?wsdl 
以及以下结构: 
http://localhost:8080/axis2/services/StockQuoteService?xsd 
一旦这些urls工作,让我们快速测试一下服务。让你的浏览器访问以下URL试试: 
http://localhost:8080/axis2/rest/StockQuoteService/getPrice?symbol=IBM 
你将得到如下应答: 
    - <ns:getPriceResponse xmlns:ns="http://pojo.service.quickstart.samples/xsd"><ns:return>42</ns:return></ns:getPriceResponse>  
 
<ns:getPriceResponse xmlns:ns="http://pojo.service.quickstart.samples/xsd"><ns:return>42</ns:return></ns:getPriceResponse>
如果你像这样调用update方法: 
http://localhost:8080/axis2/rest/StockQuoteService/update?symbol=IBM&price=100 
然后调用第一个getPrice url。你可以看到price被更新了。 
使用AXIOM构建服务 
为了使用AXIOM"从零开始"构建一个服务,执行以下步骤。 
注意包含在/samples/quickstartaxiom的目录结构: 
    - - quickstartaxiom   
-    - README.txt   
-    - build.xml   
-    - resources   
-      - META-INF   
-        - services.xml   
-        - StockQuoteService.wsdl   
-    - src   
-      - samples   
-        - quickstart   
-          - service   
-            - axiom   
-              - StockQuoteService.java   
-          - clients   
-            - AXIOMClient.java  
 
- quickstartaxiom
- README.txt
- build.xml
- resources
- META-INF
- services.xml
- StockQuoteService.wsdl
- src
- samples
- quickstart
- service
- axiom
- StockQuoteService.java
- clients
- AXIOMClient.java
由于AXIOM有一点不同,你将需要一个与POJO所用不同的services.xml文件,在Code Listing 4中显示了它的定义。 
Code Listing 4: 服务定义文件 
    - <service name="StockQuoteService" scope="application">   
-     <description>   
-         Stock Quote Service   
-     </description>   
-     <operation name="getPrice">   
-         <messageReceiver class="org.apache.<SPAN class=hilite1>axis2</SPAN>.receivers.RawXMLINOutMessageReceiver"/>   
-     </operation>   
-     <operation name="update">   
-         <messageReceiver class="org.apache.<SPAN class=hilite1>axis2</SPAN>.receivers.RawXMLINOnlyMessageReceiver"/>   
-     </operation>   
-     <parameter name="ServiceClass">samples.quickstart.service.axiom.StockQuoteService</parameter>   
- </service>  
 
<service name="StockQuoteService" scope="application">
<description>
Stock Quote Service
</description>
<operation name="getPrice">
<messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
</operation>
<operation name="update">
<messageReceiver class="org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver"/>
</operation>
<parameter name="ServiceClass">samples.quickstart.service.axiom.StockQuoteService</parameter>
</service>
注意,几乎是一样的,除了操作是显示地定义在service.xml文件中,而且MessageReceiver现在是RawXML。 
现在,上面提到的简单的使用Axis2库的类的StockQuoteService.java类,在Code Listing 5中定义。 
Code Listing 5:使用AXIOM的StockQuoteService类 
    - package samples.quickstart.service.axiom;   
-   
- import javax.xml.stream.XMLStreamException;   
- 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 java.util.HashMap;   
- public class StockQuoteService {   
-     private HashMap map = new HashMap();   
-   
-     public OMElement getPrice(OMElement element) throws XMLStreamException {   
-         element.build();   
-         element.detach();   
-   
-         OMElement symbolElement = element.getFirstElement();   
-         String symbol = symbolElement.getText();   
-   
-         String returnText = "42";   
-         Double price = (Double) map.get(symbol);   
-         if(price != null){   
-             returnText  = "" + price.doubleValue();   
-         }   
-         OMFactory fac = OMAbstractFactory.getOMFactory();   
-         OMNamespace omNs =   
-             fac.createOMNamespace("http://axiom.service.quickstart.samples/xsd", "tns");   
-         OMElement method = fac.createOMElement("getPriceResponse", omNs);   
-         OMElement value = fac.createOMElement("price", omNs);   
-         value.addChild(fac.createOMText(value, returnText));   
-         method.addChild(value);   
-         return method;   
-     }   
-   
-     public void update(OMElement element) throws XMLStreamException {   
-         element.build();   
-         element.detach();   
-   
-         OMElement symbolElement = element.getFirstElement();   
-         String symbol = symbolElement.getText();   
-   
-         OMElement priceElement = (OMElement)symbolElement.getNextOMSibling();   
-         String price = priceElement.getText();   
-   
-         map.put(symbol, new Double(price));   
-     }   
- }  
 
package samples.quickstart.service.axiom;
import javax.xml.stream.XMLStreamException;
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 java.util.HashMap;
public class StockQuoteService {
private HashMap map = new HashMap();
public OMElement getPrice(OMElement element) throws XMLStreamException {
element.build();
element.detach();
OMElement symbolElement = element.getFirstElement();
String symbol = symbolElement.getText();
String returnText = "42";
Double price = (Double) map.get(symbol);
if(price != null){
returnText  = "" + price.doubleValue();
}
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs =
fac.createOMNamespace("http://axiom.service.quickstart.samples/xsd", "tns");
OMElement method = fac.createOMElement("getPriceResponse", omNs);
OMElement value = fac.createOMElement("price", omNs);
value.addChild(fac.createOMText(value, returnText));
method.addChild(value);
return method;
}
public void update(OMElement element) throws XMLStreamException {
element.build();
element.detach();
OMElement symbolElement = element.getFirstElement();
String symbol = symbolElement.getText();
OMElement priceElement = (OMElement)symbolElement.getNextOMSibling();
String price = priceElement.getText();
map.put(symbol, new Double(price));
}
}
Axis2使用AXIOM,或者AXIs Object Model,一个基于StAX API(Streaming API for XML)的DOM(Document Object Model)类似的结构 
作为服务的方法必须使用OMElement作为它们的参数,OMElement表示一个XML元素,在这里它则为进来的SOAP消息的有效载荷。这里, 
你提取有效载荷元素的第一个孩子,添加文本给它,并使用它作为返回的OMElement的内容。除非这是一个"只有in"的服务,这些方法 
必须返回一个OMElement,因为它成为返回的SOAP消息的有效载荷。 
现在通过在Axis2_HOME/samples/quickstartaxiom目录键入ant generate.service来构建工程。 
把StockQuoteService.aar文件放在servlet引擎的webapps/axis2/WEB-INF/services目录,通过视察下面的服务列表来确认服务正确 
部署: 
http://localhost:8080/axis2/services/listServices 
你也可以检验以下WSDL: 
http://localhost:8080/axis2/services/StockQuoteService?wsdl 
以及以下结构: 
http://localhost:8080/axis2/services/StockQuoteService?xsd 
使用ADB生成服务 
执行以下步骤来使用Axis2 Databinding Framework(ADB)生成和部署服务。 
通过在Axis2_HOME/samples/quickstartadb目录键入以下内容来使用WSDL2Java工具生成骨架: 
%AXIS2_HOME%/bin/WSDL2Java -uri resources/META-INF/StockQuoteService.wsdl -p samples.quickstart.adb -d adb -s -ss 
-sd -ssi -o build/service 
或者在Axis2_HOME/samples/quickstartadb目录简单的键入ant generate.service 
选项-d adb指定了Axis Data Binding(ADB)。-s转换指定同步或者只模块化调用。-ss转换创建服务器端代码(骨架和相关文件)。-sd 
转换创建一个服务描述符(services.xml文件)。-ssi转换为服务骨架创建一个接口。服务文件现在应该定位于build/service。 
如果你通过使用WSDL2Java直接生成代码,下一步你需要修改生成的骨架来实现服务(如果你使用"ant generate.service",一个完全 
的骨架会自动复制并覆盖生成的那个)。 
打开build/service/src/samples/quickstart/adb/service/StockQuoteServiceSkeleton.java文件并修改它来添加你的服务的功能性 
到生成的方法,下面的Code Listing 6显示了。 
Code Listing 6:定义服务骨架文件 
    - package samples.quickstart.service.adb;   
-   
- import samples.quickstart.service.adb.xsd.GetPriceResponse;   
- import samples.quickstart.service.adb.xsd.Update;   
- import samples.quickstart.service.adb.xsd.GetPrice;   
-   
- import java.util.HashMap;   
-   
- public class StockQuoteServiceSkeleton {   
-   
-     private static HashMap map;   
-   
-     static{ map = new HashMap(); }   
-   
-     public void update(Update param0) {   
-         map.put(param0.getSymbol(), new Double(param0.getPrice()));   
-     }   
-   
-     public GetPriceResponse getPrice(GetPrice param1) {   
-         Double price = (Double) map.get(param1.getSymbol());   
-         double ret = 42;   
-         if(price != null){   
-             ret = price.doubleValue();   
-         }   
-         GetPriceResponse res =   
-                 new GetPriceResponse();   
-         res.set_return(ret);   
-         return res;   
-     }   
- }  
 
package samples.quickstart.service.adb;
import samples.quickstart.service.adb.xsd.GetPriceResponse;
import samples.quickstart.service.adb.xsd.Update;
import samples.quickstart.service.adb.xsd.GetPrice;
import java.util.HashMap;
public class StockQuoteServiceSkeleton {
private static HashMap map;
static{ map = new HashMap(); }
public void update(Update param0) {
map.put(param0.getSymbol(), new Double(param0.getPrice()));
}
public GetPriceResponse getPrice(GetPrice param1) {
Double price = (Double) map.get(param1.getSymbol());
double ret = 42;
if(price != null){
ret = price.doubleValue();
}
GetPriceResponse res =
new GetPriceResponse();
res.set_return(ret);
return res;
}
}
现在你可以通过在build/service目录键入以下命令构建工程:ant jar.server 
如果一切进展顺利,你应该在你的窗口看到BUILD SUCCESSFUL消息,而且StockQuoteService.aar文件在build/service/build/lib 
目录中。复制该文件到servlet引擎的webapps/axis2/WEB-INF/services目录。 
你可以通过视察下面的服务列表来确认服务正确部署: 
http://localhost:8080/axis2/services/listServices 
你也可以检验以下WSDL: 
http://localhost:8080/axis2/services/StockQuoteService?wsdl 
以及以下结构: 
http://localhost:8080/axis2/services/StockQuoteService?xsd 
使用XMLBeans生成服务 
执行以下步骤来使用XMLBeans生成服务。 
通过在Axis2_HOME/samples/quickstartxmlbeans目录键入以下命令来使用WSDL2Java工具生成骨架: 
%AXIS2_HOME%/bin/WSDL2Java -uri resources/META-INF/StockQuoteService.wsdl -p samples.quickstart.service.xmlbeans 
-d xmlbeans -s -ss -sd -ssi -o build/service 
或者在Axis2_HOME/sampels/quickstartxmlbeans目录简单的键入ant generate.service 
选项-d xmlbeans指定XMLBeans数据绑定。-s转换指定同步或者只是模块化调用。-ss转换创建服务器端代码(骨架和相关文件)。-sd 
转换创建一个服务描述符(services.xml文件)。-ssi转换创建一个服务骨架的接口。现在服务文件应该位于build/service。 
如果你通过使用WSDL2Java直接生成代码,下一步你需要修改生成的骨架来实现服务(如果你使用"ant generate.service",一个完全 
的骨架将被自动复制并覆盖生成的那个)。 
下一步打开build/service/src/samples/quickstart/service/xmlbeans/StockQuoteServiceSkeleton.java文件并修改它来添加你的 
服务的功能性到生成的方法(参看Code Listing 7)。 
Code Listing 7:定义服务骨架 
    - package samples.quickstart.service.xmlbeans;   
-   
- import samples.quickstart.service.xmlbeans.xsd.GetPriceDocument;   
- import samples.quickstart.service.xmlbeans.xsd.GetPriceResponseDocument;   
- import samples.quickstart.service.xmlbeans.xsd.UpdateDocument;   
-   
- import java.util.HashMap;   
-   
- public class StockQuoteServiceSkeleton implements StockQuoteServiceSkeletonInterface {   
-   
-     private static HashMap map;   
-   
-     static{ map = new HashMap(); }   
-   
-     public void update(UpdateDocument param0) {   
-     }   
-   
-     public GetPriceResponseDocument getPrice(GetPriceDocument param1) {   
-     }   
- }  
 
package samples.quickstart.service.xmlbeans;
import samples.quickstart.service.xmlbeans.xsd.GetPriceDocument;
import samples.quickstart.service.xmlbeans.xsd.GetPriceResponseDocument;
import samples.quickstart.service.xmlbeans.xsd.UpdateDocument;
import java.util.HashMap;
public class StockQuoteServiceSkeleton implements StockQuoteServiceSkeletonInterface {
private static HashMap map;
static{ map = new HashMap(); }
public void update(UpdateDocument param0) {
}
public GetPriceResponseDocument getPrice(GetPriceDocument param1) {
}
}
通过在build/service目录键入命令ant jar.server构建项目,该目录包含build.xml文件。 
如果一切进展顺利,你应该在你的窗口看到BUILD SUCCESSFUL消息,而且StockQuoteService.aar文件位于新创建的build/service/ 
build/lib目录。复制该文件到servlet引擎的webapps/axis2/WEB-INF/services目录。 
你可以通过视察下面的服务列表来确认服务正确部署: 
http://localhost:8080/axis2/services/listServices 
你也可以检验以下WSDL: 
http://localhost:8080/axis2/services/StockQuoteService?wsdl 
以及以下结构: 
http://localhost:8080/axis2/services/StockQuoteService?xsd 
使用JiBX生成服务 
执行以下步骤来使用JiBX数据绑定生成和部署服务。 
通过在Axis2_HOME/samples/quickstartjibx目录的控制台键入以下内容来使用WSDL2Java工具生成骨架: 
%AXIS2_HOME%/bin/wsdl2java -uri resources/META-INF/StockQuoteService.wsdl -p samples.quickstart.service.jibx -d jibx 
-s -ss -sd -ssi -uw -o build/service 
或者在Axis2_HOME/samples/quickstartjibx目录简单的键入"ant generate.service" 
选项-d jibx指定了JiBX数据绑定。-s转换指定同步或者只是模块化调用。-ss转换创建服务器端代码(骨架和相关文件)。-sd转换创建 
一个服务描述符(services.xml文件)。-ssi转换创建服务骨架的接口。-uw转换解开传递给服务操作和从服务操作传递出去的参数,来 
创建一个更自然的编程接口。 
在运行WSDL2Java后,服务文件应该位于build/service。如果你通过使用WSDL2Java直接生成代码,下一步你需要修改生成的骨架来 
实现服务(如果你使用"ant generate.service"则一个完全的骨架将自动被复制并覆盖生成的那个)。打开build/service/src/samples 
/quickstart/service/jibx/StockQuoteServiceSkeleton.java文件并修改它来添加你的服务的功能性到生成的方法,在Code Listing 
8中显示了。 
Code Listing 8:定义服务骨架文件 
    - package samples.quickstart.service.jibx;   
-   
- import java.util.HashMap;   
-   
- public class StockQuoteServiceSkeleton implements StockQuoteServiceSkeletonInterface {   
-     private HashMap map = new HashMap();   
-   
-     public void update(String symbol, Double price) {   
-         map.put(symbol, price);   
-     }   
-   
-     public Double getPrice(String symbol) {   
-         Double ret = (Double) map.get(symbol);   
-         if (ret == null) {   
-             ret = new Double(42.0);   
-         }   
-         return ret;   
-     }   
- }  
 
package samples.quickstart.service.jibx;
import java.util.HashMap;
public class StockQuoteServiceSkeleton implements StockQuoteServiceSkeletonInterface {
private HashMap map = new HashMap();
public void update(String symbol, Double price) {
map.put(symbol, price);
}
public Double getPrice(String symbol) {
Double ret = (Double) map.get(symbol);
if (ret == null) {
ret = new Double(42.0);
}
return ret;
}
}
现在你可以通过在build/service目录键入命令ant jar.server构建工程 
如果一切进展顺利,你应该在你的窗口看到BUILD SUCCESSFUL消息,并且StockQuoteService.aar文件位于build/service/build/lib 
目录。复制该文件到servlet引擎的webapps/axis2/WEB-INF/services目录。 
你可以通过视察下面的服务列表来确认服务正确部署: 
http://localhost:8080/axis2/services/listServices 
你也可以检验以下WSDL: 
http://localhost:8080/axis2/services/StockQuoteService?wsdl 
以及以下结构: 
http://localhost:8080/axis2/services/StockQuoteService?xsd 
对于和Axis2使用JiBX的更多信息,参考[urlhttp://ws.apache.org/axis2/1_1_1/jibx/jibx-quotegen-integration.html]JiBX代码生成集成[/url]。你也可以检查JiBX Axis2 Wiki页面得到更多同Axis2使用 
JiBX的更新信息。 
创建客户端 
在这个部分,我们将看看基于StockQuoteService类创建客户端的四种方式:构建基于AXIOM的客户端,使用Axis2 Databinding Frame 
work(ADB)生成客户端,使用XMLBeans生成客户端,使用JiBX生成客户端。 
使用AXIOM创建一个客户端 
执行以下步骤来使用AXIOM构建一个客户端。 
也注意在使用AXIOM创建服务部分显示的目录结构,为了完整性下面的重复了。 
    - - quickstartaxiom   
-    - README.txt   
-    - build.xml   
-    - resources   
-      - META-INF   
-        - services.xml   
-        - StockQuoteService.wsdl   
-    - src   
-      - samples   
-        - quickstart   
-          - service   
-            - axiom   
-              - StockQuoteService.java   
-          - clients   
-            - AXIOMClient.java  
 
- quickstartaxiom
- README.txt
- build.xml
- resources
- META-INF
- services.xml
- StockQuoteService.wsdl
- src
- samples
- quickstart
- service
- axiom
- StockQuoteService.java
- clients
- AXIOMClient.java
上面提到的AXIOMClient.java类的定义显示在下面的Code Listing 9。 
Code Listing 9:使用AXIOM的AXIOMClient类 
    - package samples.quickstart.clients;   
-   
- 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.<SPAN class=hilite1>axis2</SPAN>.Constants;   
- import org.apache.<SPAN class=hilite1>axis2</SPAN>.addressing.EndpointReference;   
- import org.apache.<SPAN class=hilite1>axis2</SPAN>.client.Options;   
- import org.apache.<SPAN class=hilite1>axis2</SPAN>.client.ServiceClient;   
-   
- public class AXIOMClient {   
-   
-     private static EndpointReference targetEPR =    
-         new EndpointReference("http://localhost:8080/<SPAN class=hilite1>axis2</SPAN>/services/StockQuoteService");   
-   
-     public static OMElement getPricePayload(String symbol) {   
-         OMFactory fac = OMAbstractFactory.getOMFactory();   
-         OMNamespace omNs = fac.createOMNamespace("http://axiom.service.quickstart.samples/xsd", "tns");   
-   
-         OMElement method = fac.createOMElement("getPrice", omNs);   
-         OMElement value = fac.createOMElement("symbol", omNs);   
-         value.addChild(fac.createOMText(value, symbol));   
-         method.addChild(value);   
-         return method;   
-     }   
-   
-     public static OMElement updatePayload(String symbol, double price) {   
-         OMFactory fac = OMAbstractFactory.getOMFactory();   
-         OMNamespace omNs = fac.createOMNamespace("http://axiom.service.quickstart.samples/xsd", "tns");   
-   
-         OMElement method = fac.createOMElement("update", omNs);   
-   
-         OMElement value1 = fac.createOMElement("symbol", omNs);   
-         value1.addChild(fac.createOMText(value1, symbol));   
-         method.addChild(value1);   
-   
-         OMElement value2 = fac.createOMElement("price", omNs);   
-         value2.addChild(fac.createOMText(value2,   
-                                          Double.toString(price)));   
-         method.addChild(value2);   
-         return method;   
-     }   
-   
-     public static void main(String[] args) {   
-         try {   
-             OMElement getPricePayload = getPricePayload("WSO");   
-             OMElement updatePayload = updatePayload("WSO", 123.42);   
-             Options options = new Options();   
-             options.setTo(targetEPR);   
-             options.setTransportInProtocol(Constants.TRANSPORT_HTTP);   
-   
-             ServiceClient sender = new ServiceClient();   
-             sender.setOptions(options);   
-   
-             sender.fireAndForget(updatePayload);   
-             System.err.println("done");   
-             OMElement result = sender.sendReceive(getPricePayload);   
-   
-             String response = result.getFirstElement().getText();   
-             System.err.println("Current price of WSO: " + response);   
-   
-         } catch (Exception e) {   
-             e.printStackTrace();   
-         }   
-     }   
-        
- }  
 
package samples.quickstart.clients;
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.Constants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
public class AXIOMClient {
private static EndpointReference targetEPR =
new EndpointReference("http://localhost:8080/axis2/services/StockQuoteService");
public static OMElement getPricePayload(String symbol) {
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace("http://axiom.service.quickstart.samples/xsd", "tns");
OMElement method = fac.createOMElement("getPrice", omNs);
OMElement value = fac.createOMElement("symbol", omNs);
value.addChild(fac.createOMText(value, symbol));
method.addChild(value);
return method;
}
public static OMElement updatePayload(String symbol, double price) {
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace("http://axiom.service.quickstart.samples/xsd", "tns");
OMElement method = fac.createOMElement("update", omNs);
OMElement value1 = fac.createOMElement("symbol", omNs);
value1.addChild(fac.createOMText(value1, symbol));
method.addChild(value1);
OMElement value2 = fac.createOMElement("price", omNs);
value2.addChild(fac.createOMText(value2,
Double.toString(price)));
method.addChild(value2);
return method;
}
public static void main(String[] args) {
try {
OMElement getPricePayload = getPricePayload("WSO");
OMElement updatePayload = updatePayload("WSO", 123.42);
Options options = new Options();
options.setTo(targetEPR);
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
ServiceClient sender = new ServiceClient();
sender.setOptions(options);
sender.fireAndForget(updatePayload);
System.err.println("done");
OMElement result = sender.sendReceive(getPricePayload);
String response = result.getFirstElement().getText();
System.err.println("Current price of WSO: " + response);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Axis2使用AXIOM,或者AXIs Object Model,一个基于StAX API(Streaming API for XML)的DOM(Document Object Model)类似的结构 
这里你为服务的update和getPrice方法建立有效载荷。有效载荷的创建类似于你为AXIOM服务创建getPriceResponse有效载荷。然后 
你创建Options类,并创建用来与服务交流的ServiceClient。首先你调用update方法,一个什么也不返回的fireAndForget方法。最后 
你调用getPrice方法,并从服务得到当前价格并显示它。 
现在你可以通过在Axis2_HOME/samples/quickstartaxiom目录键入ant run.client构建并运行AXIOM客户端。 
你应该得到以下输出: 
    - done   
- Current price of WSO: 123.42  
 
done
Current price of WSO: 123.42
使用ADB生成一个客户端 
执行以下步骤来使用Axis Data Binding(ADB)构建一个客户端。 
通过在Axis2_HOME/samples/quickstartadb目录键入以下命令来生成客户端数据绑定: 
%AXIS2_HOME%/bin/WSDL2Java -uri resources/META-INF/StockQuoteService.wsdl -p samples.quickstart.clients -d adb -s 
-o build/client 
或者在Axis2_HOME/samples/quickstartadb目录简单的键入ant generate.client。 
下一步看看quickstartadb/src/samples/quickstart/clients/ADBClient.java,并看看它在Code Listing 10中是怎样定义的。 
Code Listing 10:ADBClient类 
    - package samples.quickstart.clients;   
-   
- import samples.quickstart.service.adb.StockQuoteServiceStub;   
-   
- public class ADBClient{   
-     public static void main(java.lang.String args[]){   
-         try{   
-             StockQuoteServiceStub stub =   
-                 new StockQuoteServiceStub   
-                 ("http://localhost:8080/<SPAN class=hilite1>axis2</SPAN>/services/StockQuoteService");   
-   
-             getPrice(stub);   
-             update(stub);   
-   
-         } catch(Exception e){   
-             e.printStackTrace();   
-             System.err.println("\n\n\n");   
-         }   
-     }   
-   
-       
-     public static void update(StockQuoteServiceStub stub){   
-         try{   
-             StockQuoteServiceStub.Update req = new StockQuoteServiceStub.Update();   
-             req.setSymbol ("ABC");   
-             req.setPrice (42.35);   
-   
-             stub.update(req);   
-             System.err.println("done");   
-         } catch(Exception e){   
-             e.printStackTrace();   
-             System.err.println("\n\n\n");   
-         }   
-     }   
-   
-       
-     public static void getPrice(StockQuoteServiceStub stub){   
-         try{   
-             StockQuoteServiceStub.GetPrice req = new StockQuoteServiceStub.GetPrice();   
-   
-             req.setSymbol("ABC");   
-   
-             StockQuoteServiceStub.GetPriceResponse res =   
-                 stub.getPrice(req);   
-   
-             System.err.println(res.get_return());   
-         } catch(Exception e){   
-             e.printStackTrace();   
-             System.err.println("\n\n\n");   
-         }   
-     }   
-   
- }  
 
package samples.quickstart.clients;
import samples.quickstart.service.adb.StockQuoteServiceStub;
public class ADBClient{
public static void main(java.lang.String args[]){
try{
StockQuoteServiceStub stub =
new StockQuoteServiceStub
("http://localhost:8080/axis2/services/StockQuoteService");
getPrice(stub);
update(stub);
} catch(Exception e){
e.printStackTrace();
System.err.println("\n\n\n");
}
}
/* fire and forget */
public static void update(StockQuoteServiceStub stub){
try{
StockQuoteServiceStub.Update req = new StockQuoteServiceStub.Update();
req.setSymbol ("ABC");
req.setPrice (42.35);
stub.update(req);
System.err.println("done");
} catch(Exception e){
e.printStackTrace();
System.err.println("\n\n\n");
}
}
/* two way call/receive */
public static void getPrice(StockQuoteServiceStub stub){
try{
StockQuoteServiceStub.GetPrice req = new StockQuoteServiceStub.GetPrice();
req.setSymbol("ABC");
StockQuoteServiceStub.GetPriceResponse res =
stub.getPrice(req);
System.err.println(res.get_return());
} catch(Exception e){
e.printStackTrace();
System.err.println("\n\n\n");
}
}
}
该类使用你创建的Axis Data Bindings创建一个客户端存根。然后它在Web服务上调用getPrice和update操作。getPrice方法操作创建 
GetPrice有效载荷并设置symbol为ABC。然后它发送请求并显示当前价格。update方法创建一个Update有效载荷,设置symbol为ABC及 
price为42.35。 
现在通过在Axis2_HOME/samples/quickstartadb目录键入ant run.client来构建并运行客户端。 
你应该得到以下输出: 
42
done
使用XMLBeans生成一个客户端 
执行以下步骤来使用XMLBeans数据绑定来构建一个客户端。 
通过在xmlbeansClient目录键入以下命令来生成数据绑定: 
%AXIS2_HOME%/bin/WSDL2Java -uri resources/META-INF/StockQuoteService.wsdl -p samples.quickstart.service.xmlbeans -d 
xmlbeans -s -o build/client 
或者简单的在Axis2_HOME/samples/quickstartxmlbeans目录下键入ant generate.client。 
注意这只会创建客户端存根代码而不会创建服务器端代码。 
下一步看看quickstartxmlbeans/src/samples/quickstart/clients/XMLBEANSClient.java,并在Code Listing 11看看它怎样定义的 
Code Listing 11:XMLBEANSClient类 
    - package samples.quickstart.clients;   
-   
- import samples.quickstart.service.xmlbeans.StockQuoteServiceStub;   
- import samples.quickstart.service.xmlbeans.xsd.GetPriceDocument;   
- import samples.quickstart.service.xmlbeans.xsd.GetPriceResponseDocument;   
- import samples.quickstart.service.xmlbeans.xsd.UpdateDocument;   
-   
- public class XMLBEANSClient{   
-   
-     public static void main(java.lang.String args[]){   
-         try{   
-             StockQuoteServiceStub stub =   
-                 new StockQuoteServiceStub   
-                 ("http://localhost:8080/<SPAN class=hilite1>axis2</SPAN>/services/StockQuoteService");   
-   
-             getPrice(stub);   
-             update(stub);   
-   
-         } catch(Exception e){   
-             e.printStackTrace();   
-             System.err.println("\n\n\n");   
-         }   
-     }   
-   
-       
-     public static void update(StockQuoteServiceStub stub){   
-         try{   
-             UpdateDocument reqDoc = UpdateDocument.Factory.newInstance();   
-             UpdateDocument.Update req = reqDoc.addNewUpdate();   
-             req.setSymbol ("ABC");   
-             req.setPrice (42.32);   
-   
-             stub.update(reqDoc);   
-             System.err.println("done");   
-         } catch(Exception e){   
-             e.printStackTrace();   
-             System.err.println("\n\n\n");   
-         }   
-     }   
-   
-       
-     public static void getPrice(StockQuoteServiceStub stub){   
-         try{   
-             GetPriceDocument reqDoc = GetPriceDocument.Factory.newInstance();   
-             GetPriceDocument.GetPrice req = reqDoc.addNewGetPrice();   
-             req.setSymbol("ABC");   
-   
-             GetPriceResponseDocument res =   
-                 stub.getPrice(reqDoc);   
-   
-             System.err.println(res.getGetPriceResponse().getReturn());   
-         } catch(Exception e){   
-             e.printStackTrace();   
-             System.err.println("\n\n\n");   
-         }   
-     }   
- }  
 
package samples.quickstart.clients;
import samples.quickstart.service.xmlbeans.StockQuoteServiceStub;
import samples.quickstart.service.xmlbeans.xsd.GetPriceDocument;
import samples.quickstart.service.xmlbeans.xsd.GetPriceResponseDocument;
import samples.quickstart.service.xmlbeans.xsd.UpdateDocument;
public class XMLBEANSClient{
public static void main(java.lang.String args[]){
try{
StockQuoteServiceStub stub =
new StockQuoteServiceStub
("http://localhost:8080/axis2/services/StockQuoteService");
getPrice(stub);
update(stub);
} catch(Exception e){
e.printStackTrace();
System.err.println("\n\n\n");
}
}
/* fire and forget */
public static void update(StockQuoteServiceStub stub){
try{
UpdateDocument reqDoc = UpdateDocument.Factory.newInstance();
UpdateDocument.Update req = reqDoc.addNewUpdate();
req.setSymbol ("ABC");
req.setPrice (42.32);
stub.update(reqDoc);
System.err.println("done");
} catch(Exception e){
e.printStackTrace();
System.err.println("\n\n\n");
}
}
/* two way call/receive */
public static void getPrice(StockQuoteServiceStub stub){
try{
GetPriceDocument reqDoc = GetPriceDocument.Factory.newInstance();
GetPriceDocument.GetPrice req = reqDoc.addNewGetPrice();
req.setSymbol("ABC");
GetPriceResponseDocument res =
stub.getPrice(reqDoc);
System.err.println(res.getGetPriceResponse().getReturn());
} catch(Exception e){
e.printStackTrace();
System.err.println("\n\n\n");
}
}
}
该类使用你创建的XMLBeans数据绑定创建一个客户端存根,然后它在Web服务上调用getPrice和update操作。getPrice方法操作创建 
GetPriceDocument,它内部的GetPrice类,并设置symbol为ABC。然后它发送请求并得到GetPriceResponseDocument并显示当前price 
update方法创建一个UpdateDocument和Update并设置symbol为ABC及price为42.32,当完成时显示done。 
现在通过在Axis2_HOME/samples/quickstartxmlbeans目录键入ant run.client构建并运行工程。 
你应该得到下列输出: 
42
done
使用JiBX生成一个客户端 
执行以下步骤来使用JiBX构建一个客户端。 
通过在Axis2_HOME/samples/quickstartjibx目录的控制台键入以下命令来生成客户端存根: 
    - %<SPAN class=hilite1>AXIS2</SPAN>_HOME%/bin/wsdl2java -uri resources/META-INF/StockQuoteService.wsdl -p samples.quickstart.clients -d jibx -s   
- -uw -o build/client  
 
%AXIS2_HOME%/bin/wsdl2java -uri resources/META-INF/StockQuoteService.wsdl -p samples.quickstart.clients -d jibx -s
-uw -o build/client
或者简单的键入"ant generate.client"。 
下一步看看quickstartjibx/src/samples/quickstart/clients/JiBXClient.java,在Code Listing 12显示了。 
Code Listing 12:JiBXClient类 
    - package samples.quickstart.clients;   
-   
- import samples.quickstart.service.jibx.StockQuoteServiceStub;   
-   
- public class JiBXClient{   
-     public static void main(java.lang.String args[]){   
-         try{   
-             StockQuoteServiceStub stub =   
-                 new StockQuoteServiceStub   
-                 ("http://localhost:8080/<SPAN class=hilite1>axis2</SPAN>/services/StockQuoteService");   
-   
-             getPrice(stub);   
-             update(stub);   
-   
-         } catch(Exception e){   
-             e.printStackTrace();   
-             System.err.println("\n\n\n");   
-         }   
-     }   
-   
-       
-     public static void update(StockQuoteServiceStub stub){   
-         try{   
-             stub.update("ABC", new Double(42.35));   
-             System.err.println("done");   
-         } catch(Exception e){   
-             e.printStackTrace();   
-             System.err.println("\n\n\n");   
-         }   
-     }   
-   
-       
-     public static void getPrice(StockQuoteServiceStub stub){   
-         try{   
-             System.err.println(stub.getPrice("ABC"));   
-         } catch(Exception e){   
-             e.printStackTrace();   
-             System.err.println("\n\n\n");   
-         }   
-     }   
-   
- }  
 
package samples.quickstart.clients;
import samples.quickstart.service.jibx.StockQuoteServiceStub;
public class JiBXClient{
public static void main(java.lang.String args[]){
try{
StockQuoteServiceStub stub =
new StockQuoteServiceStub
("http://localhost:8080/axis2/services/StockQuoteService");
getPrice(stub);
update(stub);
} catch(Exception e){
e.printStackTrace();
System.err.println("\n\n\n");
}
}
/* fire and forget */
public static void update(StockQuoteServiceStub stub){
try{
stub.update("ABC", new Double(42.35));
System.err.println("done");
} catch(Exception e){
e.printStackTrace();
System.err.println("\n\n\n");
}
}
/* two way call/receive */
public static void getPrice(StockQuoteServiceStub stub){
try{
System.err.println(stub.getPrice("ABC"));
} catch(Exception e){
e.printStackTrace();
System.err.println("\n\n\n");
}
}
}
该类使用创建的JiBX客户端存根在Web服务上访问getPrice和update操作。getPrice方法为股票"ABC"发送请求并显示当前price。 
update方法为股票"ABC"设置价格为42.35。 
现在通过在Axis2_HOME/samples/quickstartjibx目录的控制台键入"ant run.client[b]"来构建并运行客户端。 
你应该得到以下输出: 
42
done
参考JiBX代码生成集成来得到更多关于同Axis2使用JiBX的信息细节。 
[b]总结 
Axis2是一个立刻让web服务运行起来的灵活和健壮的方式。本指南呈现了创建一个可以在Axis2上部署的服务的五种方法。现在你拥有 
了使用多种不同技术来创建Web服务的灵活性。 
进一步学习 
Apache Axis2-http://ws.apache.org/axis2/ 
Axis2 Architecture-http://ws.apache.org/axis2/1_0/Axis2ArchitectureGuide.html 
Introduction to Apache Axis2-http://www.redhat.com/magazine/021jul06/features/apache_axis2/ 
Working With Apache Axis2-http://www.wso2.net/articles/axis2/java/2006/09/13/working-with-axis2