Consuming External Web Service in Apex – Salesforce

One of the feature we have in Salesforce is that we can easily consume External Web Services. In this article, we will learn step by step demo of consuming Web Service in Apex. There are many public websites available to consume Web Service and one of them, I am using in this article is http://www.webservicex.net , from this location we are using Stock Quote Webservice. To consume this, we need WSDL.

The Web Services Description Language (WSDL) is an XML-based interface description language that is used for describing the functionality offered by a Web Service.

WSDL have to be downloaded from this location. We need this WSDL in later part of this tutorial.

Once, WSDL is downloaded and saved on local drive. We have to go to Salesforce and navigate to “Setup | Develop | Apex Classes”. On right hand side, you will find button named as “Generate from WSDL”. This button will generate equivalent Apex class to support Webservice call. In some Programming languages, these classes are known as Proxy classes or Stubs.

When we click on “Generate from WSDL” button, it will prompt for WSDL File. Select WSDL file downloaded previously and click on “Parse WSDL” button. On next page you will get this error : “Failed to parse wsdl: Found more than one wsdl:portType. WSDL with multiple portType not supported”.

In some cases you may also get error like : “Failed to parse wsdl: Found more than one wsdl:binding. WSDL with multiple binding not supported”.

Intentionally, I have used this WSDL to explain that currently Salesforce supports only single portType and binding.

PortType : defines a web service, the operations that can be performed, and the messages that are involved.
Binding : WSDL bindings defines the message format and protocol details for a web service.

Reason, we are getting an error because “wsdltoApex” doesnt support multiple PortType, Binding, SOAP 1.2 and Schema imports. You can read more here from Salesforce documentation.

How to resolve multiple portType and Binding error in Apex while generating stubs ?

We have to modify downloaded WSDL to make sure it only contains Single Binding and single PortType. Before modifying I would suggest to read about WSDL elements. I have uploaded both versions of WSDL (Please change attached file extensions from txt to xml). First one is Actual WSDL and second I have modified to remove errors. You can compare both and check how I removed multiple PortType and Binding elements from WSDL.

  1. Stockquote Actual WSDL File (Change extension from txt to xml)
  2. Stockquote Updated WSDL File (Change extension from txt to xml)

Once, you modify your wsdl, try to generate Apex class again and this time you will be able to generate class without any error.

Generating Apex from WSDL in Salesforce
Generating Apex from WSDL in Salesforce

So, here we have successfully generated Stub classes for Webservice.

How to use generated web-service Apex stub ?

Before trying to use webservice, we have to inform Salesforce that our code will try to get some Data from External source (rather interact with external system). And therefore Remote Site Setting comes into picture.

Navigate to “Setup | Security Control | Remote Site Settings“.

Create new Site setting for URL “http://www.webservicex.net“. If we skip this step, we will endup with error like “Unauthorized Endpoint”.

We can use generated Apex class in Visualforce or some other location. To keep this tutorial simple, I am using “Developer Console”. Open Developer Console and press “Ctrl+E”.

wwwWebservicexNet.StockQuoteSoap proxyClass = new wwwWebservicexNet.StockQuoteSoap();
String retVal = proxyClass.GetQuote('CTSH');
System.debug(retVal);

In above code “CTSH” is Stock symbol for Cognizant Technology Solution. You can use any other valid Stock Symbol. Output will be visible in Console Log. We can use this output as per our need

How you will find that which Class to instantiate ?
As shown in above code, I have created Object for “wwwWebservicexNet.StockQuoteSoap”.  I was able to identify that which class to instantiate? I was able to identify by porttype element name from WSDL.

How to increase Time out in Webservice ?

You may get Timeout exception while calling webservice. Default time is 10sec (At time of writing this tutorial, may change in future release). we can use “timeout_x” property to increase time to wait for response from web service. So above code can be re-written as

wwwWebservicexNet.StockQuoteSoap proxyClass = new wwwWebservicexNet.StockQuoteSoap();
proxyClass.timeout_x = 20000 ; // timeout in milliseconds
String retVal = proxyClass.GetQuote('CTSH');
System.debug(retVal);

Some Known Limitations to WSDL2Apex :

  1. It does not support multiple port bindings.
  2. Inheritance is not supported in wsdl to APEX conversion.
  3. Complex Object types such as Enumeration are not supported.
  4. WSDL Import functionality is not supported.

I hope this tutorial will be helpful for newbies. Please post your comment and feedback about this tutorial. I will be delighted to answer your query about this article.

Posted

in

,

by


Related Posts

Comments

47 responses to “Consuming External Web Service in Apex – Salesforce”

  1. Vineet Puranik Avatar
    Vineet Puranik

    Nice Tutorial

  2. Gautham Korada Avatar
    Gautham Korada

    Amazing tutorial..but i am struct up near removing the error related to MultiplePort binding because the 2 files given seems the same..not sure if i am looking at it correctly..pls help me

    1. JitendraZaa Avatar
      JitendraZaa

      Hi Gautam, If you compare both File, One is larger in size and one is smaller. Larger is original and will not work. Smaller size is updated and will work. You can use Notepad++ to compare XML Files

      1. Gautham Korada Avatar
        Gautham Korada

        I did the same Jitendra, tried comparing in Notepad++ ..ok anyway will give another try..

        1. Gautham Korada Avatar
          Gautham Korada

          I m sorry Jitendra, Now i see it..thank you.

          1. Gautham Korada Avatar
            Gautham Korada

            Jitendra, I have tried one more WSDL from the same website which is for Currency Convertor, but i m getting an error while parsing..

            Error: Failed to parse wsdl: Parse error: Found invalid XML. end tag name must match start tag name
            from line 200 (position: TEXT seen …
            ZWD-Zimbabwe Dollar… @200:3628)

            But i see all the tags are properly matching ..kindly suggest me where i need to modify in order to PARSE.

          2. Gautham Korada Avatar
            Gautham Korada

            Atleast give me an idea how to call StockQuote from a VF page.

          3. lakshminarayana Avatar
            lakshminarayana

            Hey , did u resolved that error.?
            if u did it tel me how to work with it.

      2. sudha Avatar
        sudha

        hi could u provide Tutorial on REST API integration

        1. JitendraZaa Avatar
          JitendraZaa

          What kind of REST demo you are looking for exactly ? There is endless possibilities here.

          1. sudha Avatar
            sudha

            k i dont have much idea,thats y.pls…

          2. JitendraZaa Avatar
            JitendraZaa

            Please check this post about REST API. https://jitendrazaa.com/blog/salesforce/salesforce-rest-api-playground/

      3. sudha Avatar
        sudha

        hi i m getting error while execute in Anonymous Window

        1. JitendraZaa Avatar
          JitendraZaa

          Execute it using VF page please.. Anonymous window is not useful in Async call…

          1. sudha Avatar
            sudha

            even in visualforce also i am getting same error

  3. ganesh.jujjuru Avatar
    ganesh.jujjuru

    hi shiva,
    i was trying to do example of .net integration, But iam facing the below error

    System.CalloutException: Web service callout failed: WebService returned a SOAP Fault: System.Web.Services.Protocols.SoapException: Server was unable to process request. —> System.IO.IOException: There is not enough space on the disk. at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) at System.IO.FileStream.WriteCore(Byte[] buffer, Int32 offset, Int32 count) at System.IO.FileStream.FlushWrite(Boolean calledFromFinalizer) at System.IO.FileStream.Dispose(Boolean disposing) at System.IO.Stream.Close() at System.IO.StreamWriter.Dispose(Boolean disposing) at System.IO.TextWriter.Dispose() at Microsoft.CSharp.CSharpCodeGenerator.FromSourceBatch(CompilerParameters options, String[] sources) at Microsoft.CSharp.CSharpCodeGenerator.System.CodeDom.Compiler.ICodeCompiler.CompileAssemblyFromSourceBatch(CompilerParameters options, String[] sources) at System.CodeDom.Compiler.CodeDomProvider.CompileAssemblyFromSource(CompilerParameters options, String[] sources) at System.Xml.Serialization.Compiler.Compile(Assembly parent, String ns, XmlSerializerCompilerParameters xmlParameters, Evidence evidence) at System.Xml.Serialization.TempAssembly.GenerateAssembly(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, Evidence evidence, XmlSerializerCompilerParameters parameters, Assembly assembly, Hashtable assemblies) at System.Xml.Serialization.TempAssembly..ctor(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, String location, Evidence evidence) at System.Xml.Serialization.XmlSerializer.FromMappings(XmlMapping[] mappings, Type type) at System.Web.Services.Protocols.SoapServerType..ctor(Type type, WebServiceProtocols protocolsSupported) at System.Web.Services.Protocols.SoapServerProtocol.Initialize() at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing) — End of inner exception stack trace — faultcode=soap:Server faultactor=: Class.ganesh1234.wwwWebservicexNet.StockQuoteSoap.GetQuote: line 25, column 1 AnonymousBlock: line 2, column 1 AnonymousBlock: line 2, column 1

    Please rectify my error ………..Thanks in Advance Shiva

    1. JitendraZaa Avatar
      JitendraZaa

      Hi Ganesh..

      Its not related to Salesforce or .Net. Check space on your Hard disc. It is Operating System related error.

      1. ganesh.jujjuru Avatar
        ganesh.jujjuru

        Hi how much space i need in Hard disc..?

    2. kullai Avatar
      kullai

      Hi Jitendra Zaa,

      How to Updating the Second XML page is there Any Link please send me

  4. srinivas Avatar
    srinivas

    HI jithendra,
    can you explain one scenario for REST
    if we write the REST based apex class how can we generate the end-point url for the class

  5. lakshminarayana Avatar
    lakshminarayana

    hi unable to download that WSDL…can u provide me the any other links for downloading that WSDL

  6. Raghuprasad Avatar
    Raghuprasad

    Hi Jitendra,
    I’m given a WSDL wherein required parameters to send across request object are of enum types. And there are not supported in salesforce. In that case is it possible to convert them into complex/simple types ? if yes, how ?

    thanks,
    Raghuprasad

  7. raj Avatar
    raj

    Hi Jitendra,
    i am working with sfdc from couple of months still and newbie to web services.
    i have followed the steps and was able to create stub and use it in developer console. please let me how we can use the response in vf pages

    Thanks for your help
    Regards,
    Raj

    1. JitendraZaa Avatar
      JitendraZaa

      Hi Raj,
      You can call webservice in Controller class of Visualforce and save returned value in some Field. SHow that field in Viusalforce..

      1. raj Avatar
        raj

        Thank you Jitendra,

        working on the parsing the received response using dom , is there any sort of good example for restful or soap producer and consumer? This would be great help for me in understanding the both the implementations and will be useful in my another attempt of using websercies being called from a second party to transfer the acounts list and corresponding the cases list vice versa.

        Thank you
        Raj

  8. Deep Avatar
    Deep

    Elaboration is Best, Thanks I matched up with he article and was able to implement it.

  9. Deep Avatar
    Deep

    How can we display the web service response in a VF page or an Salesforce Object

  10. Krithika Avatar
    Krithika

    How do I work if I am unable to generate the WSDL classes and have to handcraft the soap calls? The external webservice has confirmed that is the approach to be taken. Do you have any samples?

  11. RAJ KIRAN Avatar
    RAJ KIRAN

    how do we write test classes for these consuming webservices??

  12. Rohit Patil Avatar
    Rohit Patil

    Hi Jitendra,
    Is it possible to consume Exchange service wsdl in salesforce?

    1. Jitendra Zaa Avatar

      You can consume any WSDL in support with some exceptions , you should go through this post which explains which component in WSDL is not supported – https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_callouts_wsdl2apex.htm

      Apex does not support any other WSDL constructs, types, or services, including:
      RPC/encoded services
      WSDL files with mulitple portTypes, multiple services, or multiple bindings
      WSDL files that import external schemas. For example, the following WSDL fragment imports an external schema, which is not supported:

  13. santosh kumar Avatar
    santosh kumar

    Hi Sending Attachment from Salesforce to external system through SOAP Call is possible?pls help me

    1. Jitendra Zaa Avatar
  14. Akshay Deshmukh Avatar
    Akshay Deshmukh

    This is really an amazing blog. Your blog has really helped me understand webservice consumption concept in apex.

    However many company’s quotes are not getting generated due to some issues with WSDL site. I tried with MSFT, CRM etc but still no luck.

    Thanks a lot.

  15. Deep Singhal Avatar
    Deep Singhal

    Hi Jitendra,
    Is there a way to trace outgoing SOAP envelope in sandboxes to help debugging the issues. I tried to play with debug level but of not much help. Now I use RequestBib/GetSandbox to trace the message after changing the endpoint. Is there a way to trace the message in debug with the actual endpoint.

    Out of business-
    I am a fan of your posts because of the knowledge and simplicity involved. It also feels good that you work for the same organization that I do :).

    1. Jitendra Zaa Avatar

      Thanks for your words @CommonIntellect:disqus

      I think Requestbin is good option. If its REST API then we can use custom object, however for SOAP API it would be tricky to capture SOAP request.

  16. Shivani Avatar
    Shivani

    Hi Jitendra,

    Its a nice tutorial. However what if WSDL file is not compatible with Salesforce? What are the options available? Can you please guide in that?

    Thanks

    1. Jitendra Zaa Avatar

      Hi Shivani,
      I would suggest to make appropriate changes to make it compatible with Salesforce. There is no thumb rule on how to achieve this, it differs as per WSDL and type of error you are getting. Other way is to use proxy webservices which will be compatible with Salesforce and source system as well or use ETL tool. As a last resort, you can use REST API and make SOAP request manually.

  17. Jignesh Avatar
    Jignesh

    Amazing blog..!!
    I want to know about the “Can we consume the Local Web service from apex ” actually i am working on the rest api from apex to external System and I want to Post callout from apex but i am facing the error of 503 “Service Unavailable” and the Url is not live so can we do the post method callout from apex ..?

    1. Jitendra Zaa Avatar

      Local webservice will not work because it needs to be on demilitarized layer. You can use Heroku for testing purpose. using Heroku is very easy

  18. Ankur Agarwal Avatar
    Ankur Agarwal

    why there are 2 classes created when you consume wsdl in sfdc.

  19. david raj Avatar
    david raj

    How do i get the status code of the SOAP webservice Transaction

  20. […] Issue : It was a SOAP based integration and i got struck while i was trying to call out client web portal through the api and the proxy classes that salesforce automatically Creates. […]

  21. MURALI K POLIMETLA Avatar
    MURALI K POLIMETLA

    Hi Jitendra,
    How about if the web service provider provided one-way ssl certificate with the WSDL?
    Uploading the jks file under Certificate & Key Management and referring the same in wsdl2apex is not working.
    Error: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

    1. Ravi Avatar
      Ravi

      Hi Muarali, Did your issue got resolved?

  22. Raghavendra Avatar
    Raghavendra

    I am getting the following error :

    Line: 39, Column: 1
    System.CalloutException: Web service callout failed: Unexpected element. Parser was expecting element ‘http://schemas.xmlsoap.org/soap/envelope/:Envelope’ but found ‘:html’

    1. Karthik Avatar
      Karthik

      The endpoint URL you are invoking is not responding with a SOAP message but an HTML page. Check your end point in the WSDL as might be not accessible. Test it on SOAP UI or similar tool and then copy the working endpoint and replace it in generated apex class and try again.

      public String endpoint_x

Leave a Reply to Ankur AgarwalCancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Discover more from Jitendra Zaa

Subscribe now to keep reading and get access to the full archive.

Continue Reading