Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SAP Sybase SQL Anywhere 16.0 (中文) » SQL Anywhere 服务器 - 编程 » HTTP Web 服务 » HTTP Web 服务示例 » 教程:使用 JAX-WS 访问 SOAP/DISH Web 服务

 

第 2 课:创建与 Web 服务器通信的 Java 应用程序

在本课中,您将处理从 DISH 服务生成的 WSDL 文档,并根据 WSDL 文档中定义的模式来创建 Java 应用程序,访问表数据。

前提条件

本课取决于第 1 课中执行的步骤。 请参见第 1 课:设置用于接收 SOAP 请求和发送 SOAP 响应的 Web 服务器

本课假定您拥有在教程教程:使用 JAX-WS 访问 SOAP/DISH Web 服务开头的特权部分中列出的角色和特权。

上下文和注释

编写本文档时,JDK 1.7.0 中包含 JAX-WS,且 JAX-WS 的最新版本为 2.2.7。后面的步骤均以此版本为基础。要确定您的 JDK 中是否存在 JAX-WS,请检查 JDK bin 目录中的 wsimport 应用程序。如果不存在,请转到 [external link] http://jax-ws.java.net/ 下载并安装最新版本的 JAX-WS。

本课中包含对 localhost 的引用。如果 Web 客户端与 Web 服务器运行在不同的计算机上,则使用第 1 课中 Web 服务器的主机名或 IP 地址而不是 localhost

 任务
  1. 在命令提示符下,为 Java 代码和生成的文件创建新的工作目录。转到该新目录下。

  2. 使用以下命令生成调用 DISH Web 服务和导入 WSDL 文档的接口:

    wsimport -keep "http://localhost:8082/demo/WSDish"

    wsimport 应用程序从给定的 URL 读取 WSDL 文档。它生成 .java 文件为其创建接口,然后将它们编译到 .class 文件中。

    keep 选项表示生成类文件后不应删除 .java 文件。生成的 Java 源代码可让您理解所生成的类文件。

    wsimport 应用程序会在当前工作目录中创建新的子目录结构,名为 localhost\_8082\demo\ws。以下是目录 ws 的内容列表:

    • EmployeeList.class

    • EmployeeList.java

    • EmployeeListDataset$Rowset$Row.class

    • EmployeeListDataset$Rowset.class

    • EmployeeListDataset.class

    • EmployeeListDataset.java

    • EmployeeListResponse.class

    • EmployeeListResponse.java

    • FaultMessage.class

    • FaultMessage.java

    • ObjectFactory.class

    • ObjectFactory.java

    • package-info.class

    • package-info.java

    • WSDish.class

    • WSDish.java

    • WSDishSoapPort.class

    • WSDishSoapPort.java

  3. 根据所生成源代码中定义的 dataset 对象模式,编写用于访问数据库服务器上表数据的 Java 应用程序。

    以下是可进行此操作的 Java 应用程序示例。在当前工作目录中将源代码保存为 SASoapDemo.java。您的当前工作目录中必须包含 localhost 子目录。



    // SASoapDemo.java illustrates a web service client that
    // calls the WSDish service and prints out the data.
    
    import java.util.*;
    import javax.xml.ws.*;
    import org.w3c.dom.Element;
    import org.w3c.dom.Node;
    import javax.xml.datatype.*;
    import localhost._8082.demo.ws.*;
    
    public class SASoapDemo
    {
      public static void main( String[] args )
      {
        try {
          WSDish service = new WSDish();
    
          Holder<EmployeeListDataset> response = 
              new Holder<EmployeeListDataset>();
          Holder<Integer> sqlcode = new Holder<Integer>();
                
          WSDishSoapPort port = service.getWSDishSoap();
    
          // This is the SOAP service call to EmployeeList
          port.employeeList( response, sqlcode );
    
          EmployeeListDataset result = response.value;
          EmployeeListDataset.Rowset rowset = result.getRowset();
    
          List<EmployeeListDataset.Rowset.Row> rows = rowset.getRow();
    
          String fieldType;
          String fieldName;
          String fieldValue;
          Integer fieldInt;
          XMLGregorianCalendar fieldDate;
          
          for ( int i = 0; i < rows.size(); i++ ) {
            EmployeeListDataset.Rowset.Row row = rows.get( i );
    
            fieldType = row.getEmployeeID().getDeclaredType().getSimpleName();
            fieldName = row.getEmployeeID().getName().getLocalPart();
            fieldInt = row.getEmployeeID().getValue();
            System.out.println( "(" + fieldType + ")" + fieldName + 
                                "=" + fieldInt );
            
            fieldType = row.getSurname().getDeclaredType().getSimpleName();
            fieldName = row.getSurname().getName().getLocalPart();
            fieldValue = row.getSurname().getValue();
            System.out.println( "(" + fieldType + ")" + fieldName + 
                                "=" + fieldValue );
            
            fieldType = row.getGivenName().getDeclaredType().getSimpleName();
            fieldName = row.getGivenName().getName().getLocalPart();
            fieldValue = row.getGivenName().getValue();
            System.out.println( "(" + fieldType + ")" + fieldName + 
                                 "=" + fieldValue );
            
            fieldType = row.getStartDate().getDeclaredType().getSimpleName();
            fieldName = row.getStartDate().getName().getLocalPart();
            fieldDate = row.getStartDate().getValue();
            System.out.println( "(" + fieldType + ")" + fieldName + 
                                "=" + fieldDate );
            
            if ( row.getTerminationDate() == null ) {
              fieldType = "unknown";
              fieldName = "TerminationDate";
              fieldDate = null;
            } else {
              fieldType = 
                row.getTerminationDate().getDeclaredType().getSimpleName();
              fieldName = row.getTerminationDate().getName().getLocalPart();
              fieldDate = row.getTerminationDate().getValue();
            }
            System.out.println( "(" + fieldType + ")" + fieldName + 
                                "=" + fieldDate );
            System.out.println();
          }
        }
        catch (Exception x) {
          x.printStackTrace();
        }
      }
    }

    该应用程序将服务器提供的所有列数据打印为标准的系统输出。

    注意

    该应用程序假定您的 SQL Anywhere Web 服务器按第 1 课的指示监听 8082 端口。将 import localhost._8082.demo.ws.* 代码行中的 8082 部分替换成您在启动 SQL Anywhere Web 服务器时指定的端口号。

    有关此应用程序中使用的 Java 方法的详细信息,请参见 javax.xml.bind.JAXBElement 类的 API 文档,网址为 [external link] http://docs.oracle.com/javase/

  4. 使用以下命令编译 Java 应用程序:

    javac SASoapDemo.java
  5. 使用以下命令执行应用程序:

    java SASoapDemo
  6. 应用程序向 Web 服务器发送请求。它会收到一个包含 EmployeeListResult(带有含有几个行条目的行集)的 XML 结果集响应。

结果

以下示例显示了运行中的 SASoapDemo 的输出:



(Integer)EmployeeID=102
(String)Surname=Whitney
(String)GivenName=Fran
(XMLGregorianCalendar)StartDate=1984-08-28
(unknown)TerminationDate=null

(Integer)EmployeeID=105
(String)Surname=Cobb
(String)GivenName=Matthew
(XMLGregorianCalendar)StartDate=1985-01-01
(unknown)TerminationDate=null
.
.
.
(Integer)EmployeeID=1740
(String)Surname=Nielsen
(String)GivenName=Robert
(XMLGregorianCalendar)StartDate=1994-06-24
(unknown)TerminationDate=null

(Integer)EmployeeID=1751
(String)Surname=Ahmed
(String)GivenName=Alex
(XMLGregorianCalendar)StartDate=1994-07-12
(XMLGregorianCalendar)TerminationDate=2008-04-18

仅当 TerminationDate 列值为非 NULL 时,才发送它。Java 应用程序用于检测 TerminationDate 列何时不出现。对于本示例,Employees 表的最后一行被改动,因此将设置一个非 NULL 终止日期。

以下示例显示了来自 Web 服务器的 SOAP 响应。通过执行查询得到的 SQLCODE 结果包含在响应中。



<tns:EmployeeListResponse>
 <tns:EmployeeListResult xsi:type='tns:EmployeeListDataset'>
  <tns:rowset>
    <tns:row> ... </tns:row>
    .
    .
    .
    <tns:row>
      <tns:EmployeeID xsi:type="xsd:int">1751</tns:EmployeeID>
      <tns:Surname xsi:type="xsd:string">Ahmed</tns:Surname>
      <tns:GivenName xsi:type="xsd:string">Alex</tns:GivenName>
      <tns:StartDate xsi:type="xsd:dateTime">1994-07-12</tns:StartDate>
      <tns:TerminationDate xsi:type="xsd:dateTime">2010-03-22</tns:TerminationDate>
    </tns:row>
  </tns:rowset>
 </tns:EmployeeListResult>
 <tns:sqlcode>0</tns:sqlcode>
</tns:EmployeeListResponse>

列名称和数据类型都包含在每个行集中。