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

SQL Anywhere 11.0.1 (中文) » QAnywhere » 移动 Web 服务

 

移动 Web 服务示例

此示例向您演示创建移动 Web 服务应用程序的方法。创建此应用程序只需花费几分钟,它使用 QAnywhere 的存储并转发功能,使您即使在脱机状态也可以发出气象报告请求,然后在该报告可用时查看该报告。

Global Weather Web 服务

以下代码描述一个名为 Global Weather 的 Web 服务。(这是一个从公共气象 Web 服务复制而来的 wsdl 文件。)将代码复制到一个文件,将该文件命名为 globalweather.wsdl

<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://www.webserviceX.NET" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" targetNamespace="http://www.webserviceX.NET" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
  <wsdl:types>
    <s:schema elementFormDefault="qualified" targetNamespace="http://www.webserviceX.NET">
      <s:element name="GetWeather">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="CityName" type="s:string" />
            <s:element minOccurs="0" maxOccurs="1" name="CountryName" type="s:string" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="GetWeatherResponse">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="GetWeatherResult" type="s:string" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="GetCitiesByCountry">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="CountryName" type="s:string" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="GetCitiesByCountryResponse">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="GetCitiesByCountryResult" type="s:string" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="string" nillable="true" type="s:string" />
    </s:schema>
  </wsdl:types>
  <wsdl:message name="GetWeatherSoapIn">
    <wsdl:part name="parameters" element="tns:GetWeather" />
  </wsdl:message>
  <wsdl:message name="GetWeatherSoapOut">
    <wsdl:part name="parameters" element="tns:GetWeatherResponse" />
  </wsdl:message>
  <wsdl:message name="GetCitiesByCountrySoapIn">
    <wsdl:part name="parameters" element="tns:GetCitiesByCountry" />
  </wsdl:message>
  <wsdl:message name="GetCitiesByCountrySoapOut">
    <wsdl:part name="parameters" element="tns:GetCitiesByCountryResponse" />
  </wsdl:message>
  <wsdl:message name="GetWeatherHttpGetIn">
    <wsdl:part name="CityName" type="s:string" />
    <wsdl:part name="CountryName" type="s:string" />
  </wsdl:message>
  <wsdl:message name="GetWeatherHttpGetOut">
    <wsdl:part name="Body" element="tns:string" />
  </wsdl:message>
  <wsdl:message name="GetCitiesByCountryHttpGetIn">
    <wsdl:part name="CountryName" type="s:string" />
  </wsdl:message>
  <wsdl:message name="GetCitiesByCountryHttpGetOut">
    <wsdl:part name="Body" element="tns:string" />
  </wsdl:message>
  <wsdl:message name="GetWeatherHttpPostIn">
    <wsdl:part name="CityName" type="s:string" />
    <wsdl:part name="CountryName" type="s:string" />
  </wsdl:message>
  <wsdl:message name="GetWeatherHttpPostOut">
    <wsdl:part name="Body" element="tns:string" />
  </wsdl:message>
  <wsdl:message name="GetCitiesByCountryHttpPostIn">
    <wsdl:part name="CountryName" type="s:string" />
  </wsdl:message>
  <wsdl:message name="GetCitiesByCountryHttpPostOut">
    <wsdl:part name="Body" element="tns:string" />
  </wsdl:message>
  <wsdl:portType name="GlobalWeatherSoap">
    <wsdl:operation name="GetWeather">
      <documentation xmlns="http://schemas.xmlsoap.org/wsdl/">Get weather report for all major cities around the world.</documentation>
      <wsdl:input message="tns:GetWeatherSoapIn" />
      <wsdl:output message="tns:GetWeatherSoapOut" />
    </wsdl:operation>
    <wsdl:operation name="GetCitiesByCountry">
      <documentation xmlns="http://schemas.xmlsoap.org/wsdl/">Get all major cities by country name(full / part).</documentation>
      <wsdl:input message="tns:GetCitiesByCountrySoapIn" />
      <wsdl:output message="tns:GetCitiesByCountrySoapOut" />
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:portType name="GlobalWeatherHttpGet">
    <wsdl:operation name="GetWeather">
      <documentation xmlns="http://schemas.xmlsoap.org/wsdl/">Get weather report for all major cities around the world.</documentation>
      <wsdl:input message="tns:GetWeatherHttpGetIn" />
      <wsdl:output message="tns:GetWeatherHttpGetOut" />
    </wsdl:operation>
    <wsdl:operation name="GetCitiesByCountry">
      <documentation xmlns="http://schemas.xmlsoap.org/wsdl/">Get all major cities by country name(full / part).</documentation>
      <wsdl:input message="tns:GetCitiesByCountryHttpGetIn" />
      <wsdl:output message="tns:GetCitiesByCountryHttpGetOut" />
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:portType name="GlobalWeatherHttpPost">
    <wsdl:operation name="GetWeather">
      <documentation xmlns="http://schemas.xmlsoap.org/wsdl/">Get weather report for all major cities around the world.</documentation>
      <wsdl:input message="tns:GetWeatherHttpPostIn" />
      <wsdl:output message="tns:GetWeatherHttpPostOut" />
    </wsdl:operation>
    <wsdl:operation name="GetCitiesByCountry">
      <documentation xmlns="http://schemas.xmlsoap.org/wsdl/">Get all major cities by country name(full / part).</documentation>
      <wsdl:input message="tns:GetCitiesByCountryHttpPostIn" />
      <wsdl:output message="tns:GetCitiesByCountryHttpPostOut" />
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="GlobalWeatherSoap" type="tns:GlobalWeatherSoap">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" />
    <wsdl:operation name="GetWeather">
      <soap:operation soapAction="http://www.webserviceX.NET/GetWeather" style="document" />
      <wsdl:input>
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="GetCitiesByCountry">
      <soap:operation soapAction="http://www.webserviceX.NET/GetCitiesByCountry" style="document" />
      <wsdl:input>
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:binding name="GlobalWeatherHttpGet" type="tns:GlobalWeatherHttpGet">
    <http:binding verb="GET" />
    <wsdl:operation name="GetWeather">
      <http:operation location="/GetWeather" />
      <wsdl:input>
        <http:urlEncoded />
      </wsdl:input>
      <wsdl:output>
        <mime:mimeXml part="Body" />
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="GetCitiesByCountry">
      <http:operation location="/GetCitiesByCountry" />
      <wsdl:input>
        <http:urlEncoded />
      </wsdl:input>
      <wsdl:output>
        <mime:mimeXml part="Body" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:binding name="GlobalWeatherHttpPost" type="tns:GlobalWeatherHttpPost">
    <http:binding verb="POST" />
    <wsdl:operation name="GetWeather">
      <http:operation location="/GetWeather" />
      <wsdl:input>
        <mime:content type="application/x-www-form-urlencoded" />
      </wsdl:input>
      <wsdl:output>
        <mime:mimeXml part="Body" />
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="GetCitiesByCountry">
      <http:operation location="/GetCitiesByCountry" />
      <wsdl:input>
        <mime:content type="application/x-www-form-urlencoded" />
      </wsdl:input>
      <wsdl:output>
        <mime:mimeXml part="Body" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="GlobalWeather">
    <wsdl:port name="GlobalWeatherSoap" binding="tns:GlobalWeatherSoap">
      <soap:address location="http://www.webservicex.net/globalweather.asmx" />
    </wsdl:port>
    <wsdl:port name="GlobalWeatherHttpGet" binding="tns:GlobalWeatherHttpGet">
      <http:address location="http://www.webservicex.net/globalweather.asmx" />
    </wsdl:port>
    <wsdl:port name="GlobalWeatherHttpPost" binding="tns:GlobalWeatherHttpPost">
      <http:address location="http://www.webservicex.net/globalweather.asmx" />
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>
生成代理类

要创建一个移动应用程序来访问 Global Weather Web 服务,首先要运行 QAnywhere WSDL 编译器。它将生成一个代理类,这个代理类可用于应用程序中来发出此全球天气服务的请求。在本例中,应用程序是使用 Java 编写的。

wsdlc -l java globalweather.wsdl

此命令生成名为 GlobalWeatherSoap.java 的代理类,它位于当前目录的 NET\webserviceX 子目录中。此代理类是您的应用程序的服务绑定类。下面是 GlobalWeatherSoap.java 的内容:

/*
 * GlobalWeatherSoap.java
 *
 * Generated by the iAnywhere WSDL Compiler Version 10.0.1.3415
 * Do not edit this file.
 */

package NET.webserviceX;

import ianywhere.qanywhere.ws.*;
import ianywhere.qanywhere.client.QABinaryMessage;
import ianywhere.qanywhere.client.QAException;

import java.io.*;

import javax.xml.transform.*;
import javax.xml.transform.sax.*;
import javax.xml.transform.stream.*;

public class GlobalWeatherSoap extends ianywhere.qanywhere.ws.WSBase 
{

    public GlobalWeatherSoap(String iniFile) throws WSException
    {
        super(iniFile);
        init();
    }

    public GlobalWeatherSoap() throws WSException
    {
        init();
    }

    public void init() 
    {

        setServiceName("GlobalWeather");
    }


    public java.lang.String getWeather(java.lang.String cityName, 
                        java.lang.String countryName) throws QAException, WSException, WSFaultException
    {
        try {
            StringWriter sw = new StringWriter();
            SAXTransformerFactory stf = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
            TransformerHandler hd = stf.newTransformerHandler();
            QABinaryMessage qaRequestMsg = null;

            hd.setResult( new StreamResult( sw ) );
            String        responsePartName = "GetWeatherResult";
            java.lang.String    returnValue;

            writeSOAPHeader( hd, "GetWeather", "http://www.webserviceX.NET" );
            WSBaseTypeSerializer.serialize(hd,"CityName",cityName,"string","http://www.w3.org/2001/XMLSchema",true,true);
            WSBaseTypeSerializer.serialize(hd,"CountryName",countryName,"string","http://www.w3.org/2001/XMLSchema",true,true);
            writeSOAPFooter( hd, "GetWeather" );

            qaRequestMsg = createQAMessage( sw.toString(), "http://www.webserviceX.NET/GetWeather", "GetWeatherResponse" );

            WSResult wsResult = invokeWait( qaRequestMsg );

            returnValue = wsResult.getStringValue(responsePartName);

            return returnValue;
        } catch( TransformerConfigurationException e ) {
            throw new WSException( e );
        }
    }

    public WSResult asyncGetWeather(java.lang.String cityName, 
                        java.lang.String countryName) throws QAException, WSException
    {
        try {
            StringWriter sw = new StringWriter();
            SAXTransformerFactory stf = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
            TransformerHandler hd = stf.newTransformerHandler();
            QABinaryMessage qaRequestMsg = null;

            hd.setResult( new StreamResult( sw ) );

            writeSOAPHeader( hd, "GetWeather", "http://www.webserviceX.NET" );
            WSBaseTypeSerializer.serialize(hd,"CityName",cityName,"string","http://www.w3.org/2001/XMLSchema",true,true);
            WSBaseTypeSerializer.serialize(hd,"CountryName",countryName,"string","http://www.w3.org/2001/XMLSchema",true,true);
            writeSOAPFooter( hd, "GetWeather" );

            qaRequestMsg = createQAMessage( sw.toString(), "http://www.webserviceX.NET/GetWeather", "GetWeatherResponse" );

            WSResult wsResult = invoke( qaRequestMsg );

            return wsResult;
        } catch( TransformerConfigurationException e ) {
            throw new WSException( e );
        }
    }


    public java.lang.String getCitiesByCountry(java.lang.String countryName) throws QAException, WSException, WSFaultException
    {
        try {
            StringWriter sw = new StringWriter();
            SAXTransformerFactory stf = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
            TransformerHandler hd = stf.newTransformerHandler();
            QABinaryMessage qaRequestMsg = null;

            hd.setResult( new StreamResult( sw ) );
            String        responsePartName = "GetCitiesByCountryResult";
            java.lang.String    returnValue;

            writeSOAPHeader( hd, "GetCitiesByCountry", "http://www.webserviceX.NET" );
            WSBaseTypeSerializer.serialize(hd,"CountryName",countryName,"string","http://www.w3.org/2001/XMLSchema",true,true);
            writeSOAPFooter( hd, "GetCitiesByCountry" );

            qaRequestMsg = createQAMessage( sw.toString(), "http://www.webserviceX.NET/GetCitiesByCountry", "GetCitiesByCountryResponse" );

            WSResult wsResult = invokeWait( qaRequestMsg );

            returnValue = wsResult.getStringValue(responsePartName);

            return returnValue;
        } catch( TransformerConfigurationException e ) {
            throw new WSException( e );
        }
    }

    public WSResult asyncGetCitiesByCountry(java.lang.String countryName) throws QAException, WSException
    {
        try {
            StringWriter sw = new StringWriter();
            SAXTransformerFactory stf = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
            TransformerHandler hd = stf.newTransformerHandler();
            QABinaryMessage qaRequestMsg = null;

            hd.setResult( new StreamResult( sw ) );

            writeSOAPHeader( hd, "GetCitiesByCountry", "http://www.webserviceX.NET" );
            WSBaseTypeSerializer.serialize(hd,"CountryName",countryName,"string","http://www.w3.org/2001/XMLSchema",true,true);
            writeSOAPFooter( hd, "GetCitiesByCountry" );

            qaRequestMsg = createQAMessage( sw.toString(), "http://www.webserviceX.NET/GetCitiesByCountry", "GetCitiesByCountryResponse" );

            WSResult wsResult = invoke( qaRequestMsg );

            return wsResult;
        } catch( TransformerConfigurationException e ) {
            throw new WSException( e );
        }
    }
}
编写移动 Web 服务应用程序

下一步,编写使用服务绑定类来发出 Web 服务的请求并处理结果的应用程序。下面是两个应用程序,二者均脱机发出 Web 服务请求,并在可以连接时处理结果。

第一个应用程序(名为 RequestWeather)发出全球天气服务的请求并显示请求的 ID。将以下代码复制到名为 RequestWeather.java 的文件中:

import ianywhere.qanywhere.client.*;
import ianywhere.qanywhere.ws.*;
import com.myweather.GlobalWeatherSoap;

class RequestWeather
{
    public static void main( String [] args ) {
    try {
        // QAnywhere initialization
        QAManager mgr = QAManagerFactory.getInstance().createQAManager();
        mgr.open( AcknowledgementMode.EXPLICIT_ACKNOWLEDGEMENT );
        mgr.start();
     
        // Instantiate the web service proxy
        GlobalWeatherSoap service = new GlobalWeatherSoap();
        service.setQAManager( mgr );
        service.setProperty( "WS_CONNECTOR_ADDRESS", "ianywhere.connector.globalweather\\" );
     
        // Make a request to get weather for Beijing
        WSResult r = service.asyncGetWeather( "Beijing", "China" );
     
        // Display the request ID so that it can be used by ShowWeather
        System.out.println( "Request ID: " + r.getRequestID() );
     
        // QAnywhere finalization
        mgr.stop();
        mgr.close();
     
    } catch( Exception exc ) {
        System.out.println( exc.getMessage() );
    }
    }
}

第二个应用程序称为 ShowWeather,它显示给定请求 ID 的气象条件。将以下代码复制到名为 ShowWeather.java 的文件中:

import ianywhere.qanywhere.client.*;
import ianywhere.qanywhere.ws.*;
import com.myweather.GlobalWeatherSoap;

class ShowWeather
{
   public static void main( String [] args ) {
   try {
     // QAnywhere initialization
     QAManager mgr = QAManagerFactory.getInstance().createQAManager();
     mgr.open( AcknowledgementMode.EXPLICIT_ACKNOWLEDGEMENT );
     mgr.start();
     
     // Instantiate the web service proxy
     GlobalWeatherSoap service = new GlobalWeatherSoap();
     service.setQAManager( mgr );
     
     // Get the response for the specified request ID
     WSResult r = service.getResult( args[0] );
     if( r.getStatus() == WSStatus.STATUS_RESULT_AVAILABLE ) {
  System.out.println( "The weather is " + r.getStringValue( "GetWeatherResult" ) );
  r.acknowledge();
     } else {
  System.out.println( "Response not available" );
     }
     
     // QAnywhere finalization
     mgr.stop();
     mgr.close();
     
 } catch( Exception exc ) {
     System.out.println( exc.getMessage() );
 }
    }
}

编译应用程序和服务绑定类:

javac -classpath ".;%sqlany11%\java\iawsrt.jar;%sqlany11%\java\qaclient.jar" com\myweather\GlobalWeatherSoap.java RequestWeather.java
javac -classpath ".;%sqlany11%\java\iawsrt.jar;%sqlany11%\java\qaclient.jar" com\myweather\GlobalWeatherSoap.java ShowWeather.java
创建 QAnywhere 消息存储库并启动 QAnywhere 代理

您的移动 Web 服务应用程序在每个移动设备上都需要一个客户端消息存储库。它还需要服务器消息存储库,但本例使用 QAnywhere 示例服务器消息存储库。

要创建一个客户端消息存储库,请使用 dbinit 实用程序创建一个 SQL Anywhere 数据库,然后运行 QAnywhere 代理以将其设置为客户端消息存储库:

dbinit -i qanywhere.db
qaagent -q -si -c "dbf=qanywhere.db"

启动 QAnywhere 代理,连接到客户端消息存储库:

qaagent -c "dbf=qanywhere.db;eng=qanywhere;uid=ml_qa_user;pwd=qanywhere"

启动 QAnywhere 服务器:

mlsrv11 -m -zu+ -c "dsn=QAnywhere 11 Demo;uid=ml_server;pwd=sql;start=dbsrv11" -v+ -ot qanyserv.mls
♦  创建 Web 服务连接器

创建一个 Web 服务连接器,该连接器可监听发送至 GetWeather Web 服务的 QAnywhere 消息,可在消息到达时调用 Web 服务,并可将响应发送回源客户端。

  1. 打开 Sybase Central,然后单击 [连接] » [使用 QAnywhere 11 连接]。

  2. 在 [用户 ID] 字段中,键入 ml_server

  3. 在 [口令] 字段中键入 sql

  4. 单击 [ODBC 数据源名称],然后浏览到 QAnywhere 11 Demo 的位置。

  5. 单击 [OK]。

  6. 选择 [文件] » [新建] » [连接器]。

  7. 单击 [Web 服务]。单击 [下一步]。

  8. 在 [连接器名称] 字段中,键入 ianywhere.connector.globalweather。单击 [下一步]。

  9. 在 [URL] 字段中,键入 http://www.webservicex.net/globalweather.asmx。单击 [完成]。

使用 Web 服务

要对 Web 服务中获取气象报告的请求排队,请键入:

java -classpath ".;%sqlany11%\java\iawsrt.jar;%sqlany11%\java\qaclient.jar" RequestWeather

返回请求 ID。

要查看气象报告,请键入以下内容。结尾应为请求 ID,本例中为 REQ123123123。

java -classpath ".;%sqlany11%\java\iawsrt.jar;%sqlany11%\java\qaclient.jar" ShowWeather REQ123123123

返回详细的气象报告。