SOAP Services: Defining a Class from a WSDL Document

Classes can be automatically generated from a WSDL document that is stored on a local hard drive or network. Creating a class by consuming a WSDL document allows developers to make callouts to the external Web service in their Apex scripts.

Note
Use Outbound Messaging to handle integration solutions when possible. Use callouts to third-party Web services only when necessary.

To generate an Apex class from a WSDL:

  1. In the application, click Setup | Develop | Apex Classes.
  2. Click Generate from WSDL.
  3. Click Browse to navigate to a WSDL document on your local hard drive or network, or type in the full path. This WSDL document is the basis for the Apex class you are creating and must be 1 MB or less.
    Note

    The WSDL document that you specify may contain a SOAP endpoint location that references an outbound port.

    For security reasons, Salesforce.com restricts the outbound ports you may specify to one of the following:

    • 80: This port only accepts HTTP connections.
    • 443: This port only accepts HTTPS connections.
    • 7000-10000 (inclusive): These ports accept HTTP or HTTPS connections.
  4. Click Parse WSDL to verify the WSDL document contents. The application generates a default class name for each namespace in the WSDL document and reports any errors. Parsing will fail if the WSDL contains schema types or schema constructs that are not supported by Apex classes, or if the resulting classes would exceed 100,000 character limit on Apex classes. For example, the Salesforce.com SOAP API WSDL cannot be parsed.
  5. Modify the class names as desired. While you can save more than one WSDL namespace into a single class by using the same class name for each namespace, Apex classes can be no more than 100,000 characters total.
  6. Click Generate Apex. The final page of the wizard shows which classes were successfully generated, along with any errors from other classes. The page also provides a link to view the generated code if it was successful.

The successfully generated Apex class includes stub and type classes for calling the third-party Web service represented by the WSDL document. These classes allow you to call the external Web service from Apex. The SOAP request from, and response to, calls is limited to 1 MB or less.

Note
If a WSDL document contains an Apex reserved word, the word is appended with _x when the Apex class is generated. For example, upsert in a WSDL document would be converted to upsert_x in the generated Apex class. See Reserved Keywords. For details on handling characters in element names in a WSDL that are not supported in Apex variable names, see Considerations Using WSDLs.

After you have generated a class from the WSDL, you can invoke the external service referenced by the WSDL.

Note
Before you can use the samples in the rest of this topic, you must copy the Apex class docSampleClass from Understanding the Generated Code and add it to your organization.

Invoking an External Service

To invoke an external service after using its WSDL document to generate an Apex class, create an instance of the stub in your Apex script and call the methods on it. For example, to invoke the StrikeIron IP address lookup service from Apex, you could write a script similar to the following:

  // Create the stub 
    
  strikeironIplookup.DNSSoap dns = new strikeironIplookup.DNSSoap();

  // Set up the license header 
    
  dns.LicenseInfo = new strikeiron.LicenseInfo();
  dns.LicenseInfo.RegisteredUser = new strikeiron.RegisteredUser();
  dns.LicenseInfo.RegisteredUser.UserID = 'you@company.com';
  dns.LicenseInfo.RegisteredUser.Password = 'your-password';

  // Make the Web service call 
    
  strikeironIplookup.DNSInfo info = dns.DNSLookup('www.myname.com'); 

HTTP Header Support

You can set the HTTP headers on a Web service callout. For example, you can use this feature to set the value of a cookie in an authorization header. To set HTTP headers, add inputHttpHeaders_x and outputHttpHeaders_x to the stub.

Note
In API versions 16.0 and earlier, HTTP responses for callouts are always decoded using UTF-8, regardless of the Content-Type header. In API versions 17.0 and later, HTTP responses are decoded using the encoding specified in the Content-Type header.

The following samples work with the sample WSDL file in Understanding the Generated Code:

Sending HTTP Headers on a Web Service Callout

docSample.DocSamplePort stub = new docSample.DocSamplePort();
stub.inputHttpHeaders_x = new Map<String, String>();

//Setting a basic authentication header 
    

stub.inputHttpHeaders_x.put('Authorization', 'Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==');

//Setting a cookie header 
    
stub.inputHttpHeaders_x.put('Cookie', 'name=value');

//Setting a custom HTTP header 
    
stub.inputHttpHeaders_x.put('myHeader', 'myValue');

String input = 'This is the input string';
String output = stub.EchoString(input);

If a value for inputHttpHeaders_x is specified, it overrides the standard headers set.

Accessing HTTP Response Headers from a Web Service Callout Response

docSample.DocSamplePort stub = new docSample.DocSamplePort();
stub.outputHttpHeaders_x = new Map<String, String>();
String input = 'This is the input string';
String output = stub.EchoString(input);

//Getting cookie header 
    
String cookie = stub.outputHttpHeaders_x.get('Set-Cookie');

//Getting custom header 
    
String myHeader = stub.outputHttpHeaders_x.get('My-Header');

The value of outputHttpHeaders_x is null by default. You must set outputHttpHeaders_x before you have access to the content of headers in the response.

Callout Timeouts

The following limits apply when an Apex script makes a callout to an HTTP request or a Web services call. The Web services call can be a Force.com Web Services API call or any external Web services call.

The following is an example of setting a custom timeout for Web services callouts:
docSample.DocSamplePort stub = new docSample.DocSamplePort();
stub.timeout_x = 2000; // timeout in milliseconds 
    
The following is an example of setting a custom timeout for HTTP callouts:
HttpRequest req = new HttpRequest();
req.setTimeout(2000); // timeout in milliseconds 
    

Client Certificate Support

You can send a client certificate with your callout to authenticate an HTTPS connection with a specified value. Perform the following tasks to support client certificates:

  1. Set up your Web server to request the SSL client certificate, also referred to as setting up two-way SSL. This process depends on the type of Web server you use and other environmental factors. An example of how to set up two-way SSL with Tomcat on Java has been posted to this blog: http://www.vorburger.ch/blog1/2006/08/setting-up-two-way-mutual-ssl-with.html.
  2. Generate a PKCS12 key store with your client certificate.
  3. Verify that the server's trust keystore contains (accepts) your client certificate.
  4. Encode your client certificate key store in base64, and assign it to a variable on the stub, in this case, clientCert_x.
Note
The client certificate you use should be one obtained from a third party for your organization. Do not use the client certificate available from the Salesforce.com user interface.

The following example illustrates the last step of the previous procedure and works with the sample WSDL file in Understanding the Generated Code:

docSample.DocSamplePort stub = new docSample.DocSamplePort();
stub.clientCert_x =
'MIIGlgIBAzCCBlAGCSqGSIb3DQEHAaCCBkEEggY9MIIGOTCCAe4GCSqGSIb3DQEHAaCCAd8EggHb'+
'MIIB1zCCAdMGCyqGSIb3DQEMCgECoIIBgjCCAX4wKAYKKoZIhvcNAQwBAzAaBBSaUMlXnxjzpfdu'+
'6YFwZgJFMklDWFyvCnQeuZpN2E+Rb4rf9MkJ6FsmPDA9MCEwCQYFKw4DAhoFAAQU4ZKBfaXcN45w'+
'9hYm215CcA4n4d0EFJL8jr68wwKwFsVckbjyBz/zYHO6AgIEAA==';

// Password for the keystore 
    
stub.clientCertPasswd_x = 'passwd';

String input = 'This is the input string';
String output = stub.EchoString(input);

Supported WSDL Features

Apex supports only the document literal wrapped WSDL style and the following primitive and built-in datatypes:

Schema Type Apex Type
xsd:anyURI String
xsd:boolean Boolean
xsd:date Date
xsd:dateTime Datetime
xsd:double Double
xsd:float Double
xsd:int Integer
xsd:integer Integer
xsd:language String
xsd:long Long
xsd:Name String
xsd:NCName String
xsd:nonNegativeInteger Integer
xsd:NMTOKEN String
xsd:NMTOKENS String
xsd:normalizedString String
xsd:NOTATION String
xsd:positiveInteger Integer
xsd:QName String
xsd:short Integer
xsd:string String
xsd:time Datetime
xsd:token String
xsd:unsignedInt Integer
xsd:unsignedLong Long
xsd:unsignedShort Integer
Note
The Salesforce.com dataype anyType is not supported in WSDLs used to generate Apex code that is saved using API version 15.0 and later. For code saved using API version 14.0 and earlier, anyType is mapped to String.

Apex also supports the following schema constructs:

The following data types are only supported when used as call ins, that is, when an external Web service calls an Apex Web service method. These data types are not supported as callouts, that is, when an Apex Web service method calls an external Web service.

Apex does not support any other WSDL constructs, types, or services, including:

© Copyright 2000-2009 salesforce.com, inc. All rights reserved.
Various trademarks held by their respective owners.