I am trying to learn SOAP integration and have been following the online resource so far.
https://developer.salesforce.com/page/Apex_Web_Services_and_Callouts
My objective is to consume a publicly available SOAP API and display the weather for a city in a country.
Step 1 : Add the site to remote site settings
I have added the remote site as shown below.
Step 2 : Consume the WSDL
Below is the WSDL.
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://www.webserviceX.NET" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" 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">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Get weather report for all major cities around the world.</wsdl:documentation>
<wsdl:input message="tns:GetWeatherSoapIn" />
<wsdl:output message="tns:GetWeatherSoapOut" />
</wsdl:operation>
<wsdl:operation name="GetCitiesByCountry">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Get all major cities by country name(full / part).</wsdl:documentation>
<wsdl:input message="tns:GetCitiesByCountrySoapIn" />
<wsdl:output message="tns:GetCitiesByCountrySoapOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="GlobalWeatherSoap" type="tns:GlobalWeatherSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<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:service name="GlobalWeather">
<wsdl:port name="GlobalWeatherSoap" binding="tns:GlobalWeatherSoap">
<soap:address location="http://www.webservicex.net/globalweather.asmx" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Intially I encountered "multiple porttypes error" and I have removed all the porttypes except the one shown above in the WSDL.
Step 3 : Generated Apex classes from WSDL
I went to "Setup->Develop->Apex Classes" and clicked on "Generate from WSDL".
And I choose the WSDL from above.
It got successfully parsed and created two classes for me.
Class 1 :
//Generated by wsdl2apex
public class AsyncWwwWebservicexNet {
public class GetCitiesByCountryResponse_elementFuture extends System.WebServiceCalloutFuture {
public String getValue() {
wwwWebservicexNet.GetCitiesByCountryResponse_element response = (wwwWebservicexNet.GetCitiesByCountryResponse_element)System.WebServiceCallout.endInvoke(this);
return response.GetCitiesByCountryResult;
}
}
public class GetWeatherResponse_elementFuture extends System.WebServiceCalloutFuture {
public String getValue() {
wwwWebservicexNet.GetWeatherResponse_element response = (wwwWebservicexNet.GetWeatherResponse_element)System.WebServiceCallout.endInvoke(this);
return response.GetWeatherResult;
}
}
public class AsyncGlobalWeatherSoap {
public String endpoint_x = 'http://www.webservicex.net/globalweather.asmx';
public Map<String,String> inputHttpHeaders_x;
public String clientCertName_x;
public Integer timeout_x;
private String[] ns_map_type_info = new String[]{'http://www.webserviceX.NET', 'wwwWebservicexNet'};
public AsyncWwwWebservicexNet.GetCitiesByCountryResponse_elementFuture beginGetCitiesByCountry(System.Continuation continuation,String CountryName) {
wwwWebservicexNet.GetCitiesByCountry_element request_x = new wwwWebservicexNet.GetCitiesByCountry_element();
request_x.CountryName = CountryName;
return (AsyncWwwWebservicexNet.GetCitiesByCountryResponse_elementFuture) System.WebServiceCallout.beginInvoke(
this,
request_x,
AsyncWwwWebservicexNet.GetCitiesByCountryResponse_elementFuture.class,
continuation,
new String[]{endpoint_x,
'http://www.webserviceX.NET/GetCitiesByCountry',
'http://www.webserviceX.NET',
'GetCitiesByCountry',
'http://www.webserviceX.NET',
'GetCitiesByCountryResponse',
'wwwWebservicexNet.GetCitiesByCountryResponse_element'}
);
}
public AsyncWwwWebservicexNet.GetWeatherResponse_elementFuture beginGetWeather(System.Continuation continuation,String CityName,String CountryName) {
wwwWebservicexNet.GetWeather_element request_x = new wwwWebservicexNet.GetWeather_element();
request_x.CityName = CityName;
request_x.CountryName = CountryName;
return (AsyncWwwWebservicexNet.GetWeatherResponse_elementFuture) System.WebServiceCallout.beginInvoke(
this,
request_x,
AsyncWwwWebservicexNet.GetWeatherResponse_elementFuture.class,
continuation,
new String[]{endpoint_x,
'http://www.webserviceX.NET/GetWeather',
'http://www.webserviceX.NET',
'GetWeather',
'http://www.webserviceX.NET',
'GetWeatherResponse',
'wwwWebservicexNet.GetWeatherResponse_element'}
);
}
}
}
Class 2 :
//Generated by wsdl2apex
public class wwwWebservicexNet {
public class GetCitiesByCountryResponse_element {
public String GetCitiesByCountryResult;
private String[] GetCitiesByCountryResult_type_info = new String[]{'GetCitiesByCountryResult','http://www.webserviceX.NET',null,'0','1','false'};
private String[] apex_schema_type_info = new String[]{'http://www.webserviceX.NET','true','false'};
private String[] field_order_type_info = new String[]{'GetCitiesByCountryResult'};
}
public class GetCitiesByCountry_element {
public String CountryName;
private String[] CountryName_type_info = new String[]{'CountryName','http://www.webserviceX.NET',null,'0','1','false'};
private String[] apex_schema_type_info = new String[]{'http://www.webserviceX.NET','true','false'};
private String[] field_order_type_info = new String[]{'CountryName'};
}
public class GetWeatherResponse_element {
public String GetWeatherResult;
private String[] GetWeatherResult_type_info = new String[]{'GetWeatherResult','http://www.webserviceX.NET',null,'0','1','false'};
private String[] apex_schema_type_info = new String[]{'http://www.webserviceX.NET','true','false'};
private String[] field_order_type_info = new String[]{'GetWeatherResult'};
}
public class GetWeather_element {
public String CityName;
public String CountryName;
private String[] CityName_type_info = new String[]{'CityName','http://www.webserviceX.NET',null,'0','1','false'};
private String[] CountryName_type_info = new String[]{'CountryName','http://www.webserviceX.NET',null,'0','1','false'};
private String[] apex_schema_type_info = new String[]{'http://www.webserviceX.NET','true','false'};
private String[] field_order_type_info = new String[]{'CityName','CountryName'};
}
public class GlobalWeatherSoap {
public String endpoint_x = 'http://www.webservicex.net/globalweather.asmx';
public Map<String,String> inputHttpHeaders_x;
public Map<String,String> outputHttpHeaders_x;
public String clientCertName_x;
public String clientCert_x;
public String clientCertPasswd_x;
public Integer timeout_x;
private String[] ns_map_type_info = new String[]{'http://www.webserviceX.NET', 'wwwWebservicexNet'};
public String GetCitiesByCountry(String CountryName) {
wwwWebservicexNet.GetCitiesByCountry_element request_x = new wwwWebservicexNet.GetCitiesByCountry_element();
request_x.CountryName = CountryName;
wwwWebservicexNet.GetCitiesByCountryResponse_element response_x;
Map<String, wwwWebservicexNet.GetCitiesByCountryResponse_element> response_map_x = new Map<String, wwwWebservicexNet.GetCitiesByCountryResponse_element>();
response_map_x.put('response_x', response_x);
WebServiceCallout.invoke(
this,
request_x,
response_map_x,
new String[]{endpoint_x,
'http://www.webserviceX.NET/GetCitiesByCountry',
'http://www.webserviceX.NET',
'GetCitiesByCountry',
'http://www.webserviceX.NET',
'GetCitiesByCountryResponse',
'wwwWebservicexNet.GetCitiesByCountryResponse_element'}
);
response_x = response_map_x.get('response_x');
return response_x.GetCitiesByCountryResult;
}
public String GetWeather(String CityName,String CountryName) {
wwwWebservicexNet.GetWeather_element request_x = new wwwWebservicexNet.GetWeather_element();
request_x.CityName = CityName;
request_x.CountryName = CountryName;
wwwWebservicexNet.GetWeatherResponse_element response_x;
Map<String, wwwWebservicexNet.GetWeatherResponse_element> response_map_x = new Map<String, wwwWebservicexNet.GetWeatherResponse_element>();
response_map_x.put('response_x', response_x);
WebServiceCallout.invoke(
this,
request_x,
response_map_x,
new String[]{endpoint_x,
'http://www.webserviceX.NET/GetWeather',
'http://www.webserviceX.NET',
'GetWeather',
'http://www.webserviceX.NET',
'GetWeatherResponse',
'wwwWebservicexNet.GetWeatherResponse_element'}
);
response_x = response_map_x.get('response_x');
return response_x.GetWeatherResult;
}
}
}
Questions
a) Why two classes have been generated for me by WSDL2Apex ?
b) Can someone tell me how am I to actually perform the callout ?.
.Apologies if this is something trivial :)..
I have been following the resource so far and the actual call out step is not mentioned there :(.