上一篇
目    录
下一篇
  Apache Axis2用户指南 - 建立客户端

如果要建立Web service客户端,你可以手工做(参见搭建服务),但是在大多数情况下你拥有一个Web Service描述语言(WSDL)定义,它描述了客户端发送的和希望收到的消息。Axis2提供了几种方法来用该定义自动生成一个客户端。

  目录

  选择一个客户端生成方法

在生成客户端时,Axis2给你几个选择可以将WSDL映射到对象。其中三个是Axis2 DataBinding Framework, XMLBeans和JiBX databinding。所有这些方法涉及使用数据绑定来建立Java对象,这些对象来自于服务使用的XML结构,各有利弊。你也可以生成不基于数据绑定的XML in-out功能组。Axis2 Databinding Framework (ADB):ADB是生成Axis2客户端最简单的方法。在大多数情况下,所有相关的类将会建立为一个主要功能组类的内部类。ADB使用起来很容易,但是它有很多限制。它不是一个完整的schema绑定应用,对于处理类似XML Schema元素扩展和限制的结构是有困难的。XMLBeans:不象ADB,XMLBeans是一个具有完全功能的schema编译器,所以它没有类似ADB那样的限制。在实际使用时,它生成大量的文件和编程模型,并不像ADB那么直接。JiBX:JiBX是一个完整的数据绑定框架,它不仅提供了本文提到的WSDL到Java的转换,还提供了Java到XML的转换。从某种意义上说,JiBX提供了这两方面的最好解决方案。JiBX是极其灵活的,它可以让你来选择代表你条目的类,但是它建立起来比较复杂。另一方面,一旦建立起来,实际使用生成的代码和用ADB一样简单。最后,对于简单结构,ADB对你来说可能足够了。如果你需要更多的灵活性和功能,是选择XMLBeans还是JiBX依赖于你需要多少功能和灵活性,还有你对它们复杂性的容忍程度。

  生成客户端

生成和使用客户端的过程会随着你选择的生成方法的不同而有所变化。在本文的三种情况中,客户端是根据同一个WSDL文件生成的(见代码列表5)。注意文档定义了四个操作,DoInOnly,NoParameters,TwoWayOneparameterEcho和MultipleParametersAddItem。每个客户端都会包含调用这些操作的方法。(你可以从http://www.w3.org/2002/ws/desc/获得更多关于WSDL的信息。)

代码列表5:根据WSDL生成客户端
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions
   xmlns:apachesoap="http://xml.apache.org/xml-soap"

   xmlns:impl="http://apache.org/axis2/Axis2UserGuide"
   xmlns:intf="http://apache.org/axis2/Axis2UserGuide"
   xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
   xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema"

   targetNamespace="http://apache.org/axis2/Axis2UserGuide">

  <wsdl:types>
    <schema
       elementFormDefault="qualified"
       targetNamespace="http://apache.org/axis2/Axis2UserGuide"
       xmlns="http://www.w3.org/2001/XMLSchema">

      
      <!-- ELEMENTS -->
      
      <element name="DoInOnlyRequest">
        <complexType>
          <sequence>
            <element name="messageString" type="xsd:string"/>

          </sequence>
        </complexType>
      </element>
      
      <element name="TwoWayOneParameterEchoRequest">
        <complexType>
          <sequence>

            <element name="echoString" type="xsd:string"/>
          </sequence>
        </complexType>
      </element>

      <element name="TwoWayOneParameterEchoResponse">
        <complexType>
          <sequence>
            <element name="echoString" type="xsd:string"/>

          </sequence>
        </complexType>
      </element>
      
      <element name="NoParametersRequest">
        <complexType/>
      </element>

      <element name="NoParametersResponse">
        <complexType/>
      </element>
      
      <element name="MultipleParametersAddItemRequest">
        <complexType>

          <sequence>
            <element name="itemId" type="xsd:int"/>
            <element name="itemName" type="xsd:string"/>

            <element name="price" type="xsd:float"/>
            <element name="description" type="xsd:string"/>
          </sequence>

        </complexType>
      </element>

      <element name="MultipleParametersAddItemResponse">
        <complexType>
          <sequence>

          <element name="itemId" type="xsd:int"/>
          <element name="successfulAdd" type="xsd:boolean"/>
          </sequence>

        </complexType>
      </element>

    </schema>
  </wsdl:types>

  
  <!-- MESSAGES -->

  <wsdl:message name="DoInOnlyRequestMessage">
    <wsdl:part name="input" element="impl:DoInOnlyRequest"/>
  </wsdl:message>

  <wsdl:message name="TwoWayOneParameterEchoRequestMessage">
    <wsdl:part name="input" element="impl:TwoWayOneParameterEchoRequest"/>
  </wsdl:message>
  <wsdl:message name="TwoWayOneParameterEchoResponseMessage">

    <wsdl:part name="output" element="impl:TwoWayOneParameterEchoResponse"/>
  </wsdl:message>

  <wsdl:message name="NoParametersRequestMessage">
    <wsdl:part name="input" element="impl:NoParametersRequest"/>

  </wsdl:message>
  <wsdl:message name="NoParametersResponseMessage">
    <wsdl:part name="output" element="impl:NoParametersResponse"/>
  </wsdl:message>

  <wsdl:message name="MultipleParametersAddItemRequestMessage">
    <wsdl:part name="input" element="impl:MultipleParametersAddItemRequest"/>
  </wsdl:message>
  <wsdl:message name="MultipleParametersAddItemResponseMessage">

    <wsdl:part name="output" element="impl:MultipleParametersAddItemResponse"/>
  </wsdl:message>


  <!-- Port type (operations) -->

  <wsdl:portType name="Axis2UserGuidePortType">

    <wsdl:operation name="DoInOnly" parameterOrder="input">
      <wsdl:input name="DoInOnlyRequestMessage"
                  message="impl:DoInOnlyRequestMessage"/>

    </wsdl:operation>

    <wsdl:operation name="TwoWayOneParameterEcho" parameterOrder="input">
      <wsdl:input name="TwoWayOneParameterEchoRequestMessage"
                  message="impl:TwoWayOneParameterEchoRequestMessage"/>

      <wsdl:output name="TwoWayOneParameterEchoResponseMessage"
                  message="impl:TwoWayOneParameterEchoResponseMessage"/>
    </wsdl:operation>

    <wsdl:operation name="NoParameters" parameterOrder="input">

      <wsdl:input name="NoParametersRequestMessage"
                  message="impl:NoParametersRequestMessage"/>
      <wsdl:output name="NoParametersResponseMessage"
                   message="impl:NoParametersResponseMessage"/>

    </wsdl:operation>

    <wsdl:operation name="MultipleParametersAddItem" parameterOrder="input">
      <wsdl:input name="MultipleParametersAddItemRequestMessage"
                  message="impl:MultipleParametersAddItemRequestMessage"/>

      <wsdl:output name="MultipleParametersAddItemResponseMessage"
                  message="impl:MultipleParametersAddItemResponseMessage"/>
    </wsdl:operation>

  </wsdl:portType>

  <!-- BINDING (bind operations) -->
  <wsdl:binding
     name="Axis2UserGuideSoapBinding"
     type="impl:Axis2UserGuidePortType">
    <wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>

    <wsdl:operation name="DoInOnly">
      <wsdlsoap:operation soapAction="DoInOnly"/>
      <wsdl:input>
        <wsdlsoap:body use="literal"/>

      </wsdl:input>
    </wsdl:operation>

    <wsdl:operation name="TwoWayOneParameterEcho">
      <wsdlsoap:operation soapAction="TwoWayOneParameterEcho"/>
      <wsdl:input>

        <wsdlsoap:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
        <wsdlsoap:body use="literal"/>
      </wsdl:output>

    </wsdl:operation>

    <wsdl:operation name="NoParameters">
      <wsdlsoap:operation soapAction="NoParameters"/>
      <wsdl:input>
        <wsdlsoap:body use="literal"/>

      </wsdl:input>
      <wsdl:output>
        <wsdlsoap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>

    <wsdl:operation name="MultipleParametersAddItem">
      <wsdlsoap:operation soapAction="MultipleParametersAddItem"/>
      <wsdl:input>
        <wsdlsoap:body use="literal"/>

      </wsdl:input>
      <wsdl:output>
        <wsdlsoap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>

  </wsdl:binding>


  <!-- SERVICE -->

  <wsdl:service name="Axis2UserGuideService">
    <wsdl:port binding="impl:Axis2UserGuideSoapBinding"

               name="Axis2UserGuide">
      <wsdlsoap:address location="http://localhost:8080/axis2/services/Axis2UserGuide"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>



  Axis Data Binding (ADB)

要用ADB建立客户端,执行以下步骤:简要说明:
  1. 如果你还没做的话,请下载并解压Apache Axis2标准发行包。
  2. 用以下命令建立客户端功能组:
  3. %AXIS2_HOME%\bin\WSDL2Java -uri Axis2UserGuide.wsdl -p org.apache.axis2.axis2userguide -d adb -s
  4. 建立客户端(例如:Client.java),这是一个使用上面生成的功能组的Java应用程序,把它保存在org/apache/axis2/axis2userguide 目录。
  5. 搭建客户端:ant jar.client。
  6. 假设你已经有一个相应的服务,将生成的build/lib下的Axis2UserGuideService-test-client.jar文件加入到classpath,输入以下命令,就可以运行客户端了:java org.apache.axis2.axis2userguide.Client
详细说明:如果你还没做,请先下载和解压Apache Axis2标准发行包。Axis2 WAR发行包没有包括生成代码的必要工具,例如WSDL2Java。在生成客户端的ADB方法中,所有的服务功能都包含在单个类中,这叫做stub。stub包含了与定义在WSDL文件中必要的对象对应的内部类,例如,在这个WSDL中的DoInOnlyRequestMessage。一旦你有了这个功能组,你就能建立客户端了,而这个工作只需要你引用这些类和它们的方法。要生成客户端,执行代码列表6中的命令。

代码列表6 – 生成客户端
%AXIS2_HOME%\bin\WSDL2Java -uri Axis2UserGuide.wsdl -p org.apache.axis2.axis2userguide -d adb –s

这个命令分析了WSDL文件,建立了org.apache.axis2.axis2userguide 包的功能组。-d选项说明你使用ADB数据绑定方式,-s代表同步或者阻塞。换句话说,当客户端进行In-Out方式的服务调用,它将在得到一个反馈后再继续执行。一旦你运行了这个命令,你将在目录中看到两个新项目。第一个是文件build.xml,它包含了调用Ant来编译生成类的指令。第二个是src目录,它包含了实际的文件Axis2UserGuideServiceStub.java 。如果你打开这个文件,你将看到一组内部类,分别和WSDL文件中每一项相对应。你还能看到对于Axis2客户端API的调用,这些API使用AXIOM来搭建和分析输入输出消息。现在你需要一个客户端来使用这段代码。要建立一个客户端,建一个新类并将它保存为org/apache/axis2/axis2userguide 目录下的Client.java文件。它应该包含代码列表7中的内容。注意,现在使用服务被简化了,你只要建立和生成出合适的请求,并且使用功能组来发送请求到特定的方法就可以了,这些请求的名称是在WSDL文件中定义的。例如,要调用DoInOnly操作,你建立一个DoInOnlyRequest,调用它的setMessageString()方法来设置它的messageString元素的内容,并把它作为参数传递给stub.DoInOnly()。要搭建客户端,输入:ant jar.client。这个动作建立了两个新的目录,build和test。Test目录是空的,但是build目录包含了两个版本的客户端。第一个版本是一个jar文件,包括客户端类和功能组,保存在lib目录。第二个在classes目录,包含那些原始类文件。确认Axis2 lib目录下所有的jar文件都包括在classpath中。如果你有一个与这个客户端相对应的服务,你可以添加jar文件到classpath,并输入下面的命令来运行客户端:java org.apache.axis2.axis2userguide.Client(如果你没有该服务,请参考文档搭建服务。)你应该在在你的servlet容器的控制台上看到反馈。它看起来像这样:



代码列表7:Client.java
package org.apache.axis2.axis2userguide;

import org.apache.axis2.axis2userguide.Axis2UserGuideServiceStub.DoInOnlyRequest;
import org.apache.axis2.axis2userguide.Axis2UserGuideServiceStub.TwoWayOneParameterEchoRequest;
import org.apache.axis2.axis2userguide.Axis2UserGuideServiceStub.NoParametersRequest;
import org.apache.axis2.axis2userguide.Axis2UserGuideServiceStub.MultipleParametersAddItemRequest;

import org.apache.axis2.axis2userguide.Axis2UserGuideServiceStub.TwoWayOneParameterEchoResponse;
import org.apache.axis2.axis2userguide.Axis2UserGuideServiceStub.NoParametersResponse;
import org.apache.axis2.axis2userguide.Axis2UserGuideServiceStub.MultipleParametersAddItemResponse;

public class Client{
    public static void main(java.lang.String args[]){
        try{
            Axis2UserGuideServiceStub stub =
                new Axis2UserGuideServiceStub
                ("http://localhost:8080/axis2/services/Axis2UserGuideService");

            doInOnly(stub);
            twoWayOneParameterEcho(stub);
            noParameters(stub);
            multipleParameters(stub);

        } catch(Exception e){
            e.printStackTrace();
            System.out.println("\n\n\n");
        }
    }

    /* do in only */
    public static void doInOnly(Axis2UserGuideServiceStub stub){
        try{
            DoInOnlyRequest req = new DoInOnlyRequest();

            req.setMessageString("An in only request");

            stub.DoInOnly(req);
            System.out.println("done");
        } catch(Exception e){
            e.printStackTrace();
            System.out.println("\n\n\n");
        }
    }

    /* two way call/receive */
    public static void twoWayOneParameterEcho(Axis2UserGuideServiceStub stub){
        try{
            TwoWayOneParameterEchoRequest req = new TwoWayOneParameterEchoRequest();

            req.setEchoString("echo! ... echo!");

            TwoWayOneParameterEchoResponse res =
                stub.TwoWayOneParameterEcho(req);

            System.out.println(res.getEchoString());
        } catch(Exception e){
            e.printStackTrace();
            System.out.println("\n\n\n");
        }
    }

    /* No parameters */
    public static void noParameters(Axis2UserGuideServiceStub stub){
        try{
            NoParametersRequest req = new NoParametersRequest();

            System.out.println(stub.NoParameters(req));
        } catch(Exception e){
            e.printStackTrace();
            System.out.println("\n\n\n");
        }
    }

    /* multiple parameters */
    public static void multipleParameters(Axis2UserGuideServiceStub stub){
        try{
            MultipleParametersAddItemRequest req =
                new MultipleParametersAddItemRequest();

            req.setPrice((float)1.99);
            req.setItemId((int)23872983);
            req.setDescription("Must have for cooking");
            req.setItemName("flour");

            MultipleParametersAddItemResponse res =
                stub.MultipleParametersAddItem(req);

            System.out.println(res.getSuccessfulAdd());
            System.out.println(res.getItemId());
        } catch(Exception e){
            e.printStackTrace();
            System.out.println("\n\n\n");
        }
    }
}
ADB不是生成Web service客户端的唯一选择,其他的方法包括XmlBeans, JiBX, JAXME and JAXBRI。看下一部分 – 搭建服务

上一篇
目    录
下一篇