此示例向您演示创建移动 Web 服务应用程序的方法。创建此应用程序只需花费几分钟,它使用 QAnywhere 的存储并转发功能,使您即使在脱机状态也可以发出气象报告请求,然后在该报告可用时查看该报告。
以下代码描述一个名为 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 服务请求,并在可以连接时处理结果。
第一个应用程序(名为 RequestWeather)发出全球天气服务的请求并显示请求的 ID。将以下代码复制到名为 RequestWeather.java 的文件中:
import ianywhere.qanywhere.client.*; import ianywhere.qanywhere.ws.*; import NET.webserviceX.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 NET.webserviceX.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 ".;%sqlany12%\java\iawsrt.jar;%sqlany12%\java\qaclient.jar" NET.webserviceX.GlobalWeatherSoap.java RequestWeather.java javac -classpath ".;%sqlany12%\java\iawsrt.jar;%sqlany12%\java\qaclient.jar" NET.webserviceX.GlobalWeatherSoap.java ShowWeather.java |
您的移动 Web 服务应用程序在每个移动设备上都需要一个客户端消息存储库。它还需要服务器消息存储库,但本例使用 QAnywhere 示例服务器消息存储库。
要创建一个客户端消息存储库,请使用 dbinit 实用程序创建一个 SQL Anywhere 数据库,然后运行 QAnywhere 代理以将其设置为客户端消息存储库:
dbinit -i qanywhere.db qaagent -q -si -c "dbf=qanywhere.db" |
启动 QAnywhere 代理,连接到客户端消息存储库:
qaagent -c "dbf=qanywhere.db;server=qanywhere;uid=ml_qa_user;pwd=qanywhere" |
启动 QAnywhere 服务器:
mlsrv12 -m -zu+ -c "dsn=QAnywhere 12 Demo;uid=ml_server;pwd=sql;start=dbsrv12" -v+ -ot qanyserv.mls |
创建一个 Web 服务连接器,该连接器可监听发送至 GetWeather Web 服务的 QAnywhere 消息,可在消息到达时调用 Web 服务,并可将响应发送回源客户端。
打开 Sybase Central,然后单击 [连接] » [使用 QAnywhere 12 连接]。
在 [用户 ID] 字段中,键入 ml_server。
在 [口令] 字段中键入 sql。
单击 [ODBC 数据源名称],然后键入 QAnywhere 12 Demo。
单击 [连接]。
单击 [文件] » [新建] » [连接器]。
单击 [Web 服务]。单击 [下一步]。
在 [连接器名称] 字段中,键入 ianywhere.connector.globalweather。单击 [下一步]。
在 [URL] 字段中,键入 http://www.webservicex.net/globalweather.asmx。单击 [完成]。
要对 Web 服务中获取气象报告的请求排队,请键入:
java -classpath ".;%sqlany12%\java\iawsrt.jar;%sqlany12%\java\qaclient.jar" RequestWeather |
返回请求 ID。
要查看气象报告,请键入以下内容。结尾应为请求 ID,本例中为 REQ123123123。
java -classpath ".;%sqlany12%\java\iawsrt.jar;%sqlany12%\java\qaclient.jar" ShowWeather REQ123123123 |
返回详细的气象报告。
![]() |
使用DocCommentXchange讨论此页。
|
版权 © 2012, iAnywhere Solutions, Inc. - SQL Anywhere 12.0.1 |