This example shows you how to create a mobile web service application. The application, which takes just a few minutes to create, uses the QAnywhere store-and-forward functionality so that you can issue a request for a weather report even if your offline and then see the report when it is available.
The following code describes a web service called Global Weather. (It is a wsdl file that was copied from a public weather web service.) Copy the code into a file and name the file 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> |
To create a mobile application to access the Global Weather web service, first run the QAnywhere WSDL compiler. It generates a proxy class that can be used in an application to make requests of the global weather service. In this example, the application is written in Java.
wsdlc -l java globalweather.wsdl |
This command generates a proxy class called GlobalWeatherSoap.java, located in the NET\webserviceX subdirectory of the current directory. This proxy class is the service binding class for your application. The following is the content of 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 ); } } } |
Next, write applications that use the service binding class to make requests of the web service and process the results. Following are two applications, both of which make web service requests offline and process the results when a connection is available.
The first application, called RequestWeather, makes a request of the global weather service and displays the ID of the request. Copy the following code into a file called 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() ); } } } |
The second application, called ShowWeather, shows the weather conditions for a given request ID. Copy the following code into a file called 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() ); } } } |
Compile the application and the service binding class:
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 |
Your mobile web service application requires a client message store on each mobile device. It also requires a server message store, but this example uses the QAnywhere sample server message store.
To create a client message store, create a SQL Anywhere database with the dbinit utility and then run the QAnywhere Agent to set it up as a client message store:
dbinit -i qanywhere.db qaagent -q -si -c "dbf=qanywhere.db" |
Start the QAnywhere Agent to connect to your client message store:
qaagent -c "dbf=qanywhere.db;eng=qanywhere;uid=ml_qa_user;pwd=qanywhere" |
Start the QAnywhere server:
mlsrv11 -m -zu+ -c "dsn=QAnywhere 11 Demo;uid=ml_server;pwd=sql;start=dbsrv11" -v+ -ot qanyserv.mls |
Finally, create a web service connector that listens for QAnywhere messages sent to the GetWeather web service, makes web service calls when messages arrive, and sends back responses to the originating client.
Open Sybase Central and click Connections » Connect With QAnywhere 11. Enter the User ID ml_server and the Password sql. Select ODBC data source name and click Browse to locate QAnywhere 11 Demo.
To create your web service connector, choose File » New » Connector. When the Connector Wizard appears, select the Web Services option. In the wizard pages, set the following properties to match the mobile applications you created earlier in the example:
To queue up a request to get the weather report from the web service, type:
java -classpath ".;%sqlany11%\java\iawsrt.jar;%sqlany11%\java\qaclient.jar" RequestWeather |
A request ID is returned.
To see the weather report, type the following. The end should be the request ID, in this example REQ123123123.
java -classpath ".;%sqlany11%\java\iawsrt.jar;%sqlany11%\java\qaclient.jar" ShowWeather REWQ123123123 |
A detailed weather report is returned.
Send feedback about this page via email or DocCommentXchange | Copyright © 2008, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.0 |