Machine-to-Machine Salesforce Integrations in Java with REST and SOAP – Developer Relations

When doing a human-to-machine integration you should use the OAuth web or mobile flow so that the credentials never pass through the integration application. In the case of machine-to-machine integrations, the integration must have an integration user’s credentials and use either the username & password OAuth flow for REST or direct authentication for SOAP. Also, I have included both REST and SOAP because there are distinct use cases for each. REST is what most people use today because it is flexible, while SOAP is more strict but provides a better out-of-the-box experience due to the Salesforce-provided client libraries. Let’s dive into each of these.

Salesforce REST Integration with Java

REST has emerged as the de-facto standard for service integration because it is a simple protocol which uses HTTP and its semantics instead of putting the semantics into the payloads. So if you want to create an Account on Salesforce you perform an HTTP POST to with a JSON body like:

{ "Name" : "Foo, inc." }

The HTTP response code and body tell you about the success or failure of the operation. For example, a successful create will have an HTTP 201 “Created” code and a body like:

{ "id" : "001D000000IqhSLIAZ", "errors" : [ ], "success" : true }

To work with the Salesforce REST API you just need an HTTP client and a JSON library. Numerous community-maintained client libraries also exist for pretty much every programming platform. This example will just use REST directly instead of using a client library. If you would rather use a client library with Java, check out the REST API Connector.

Now let’s walk through a sample Java project that does this integration. You can see the full source on GitHub or grab a zip of the sample. For this example we need an HTTP client and a JSON library, so we’ve set those to the Apache HTTP Client and Jackson JSON library in the Maven build. The full application is in a single Java file. The easiest way to run this kind of sample is on the command line, so it first asks for the Salesforce username, password, OAuth Consumer Key, and OAuth Consumer Secret. To run this sample, create a Connected App in Salesforce to obtain the OAuth Consumer Key & Secret. This sample prompts for those values but in reality, externalize them to configuration like environment variables.

Once the username, password, and OAuth Consumer Key & Consumer Secret have been obtained we can login to obtain an access token. This uses the username & password OAuth flow. Now to actually use REST to fetch some Salesforce data! This is pretty straightforward:

final URIBuilder builder = new URIBuilder(instanceUrl); builder.setPath("/services/data/v39.0/query/") .setParameter("q", "SELECT Id, Name FROM Contact"); final HttpGet get = new HttpGet(; get.setHeader("Authorization", "Bearer " + accessToken); final HttpResponse queryResponse = httpclient.execute(get); final JsonNode queryResults = mapper.readValue(queryResponse.getEntity().getContent(), JsonNode.class);

This performs a SOQL query to fetch the Contact objects. Let’s see what it looks like when we run all this:

~/salesforce-rest-starter $ ./mvnw compile exec:java [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building salesforce-rest-starter 0.0.1-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ salesforce-rest-starter --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory /Volumes/Home/j.ward/projects/salesforce-rest-starter/src/main/resources [INFO] [INFO] --- maven-compiler-plugin:3.6.1:compile (default-compile) @ salesforce-rest-starter --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 1 source file to /Volumes/Home/j.ward/projects/salesforce-rest-starter/target/classes [INFO] [INFO] --- exec-maven-plugin:1.5.0:java (default-cli) @ salesforce-rest-starter --- Salesforce Username: [email protected] Salesforce Password: Salesforce Consumer Key: 3MVG9y6x0357HlefecAM3Fyy5j8AeQBEqRCchpemMuxwwIY7AEcFFudt Salesforce Consumer Secret: { "totalSize" : 2, "done" : true, "records" : [ { "attributes" : { "type" : "Contact", "url" : "/services/data/v20.0/sobjects/Contact/0031a000004oQ9eAAE" }, "Id" : "0031a000004oQ9eAAE", "Name" : "Rose Gonzalez" }, { "attributes" : { "type" : "Contact", "url" : "/services/data/v20.0/sobjects/Contact/0031a000004oQ9fAAE" }, "Id" : "0031a000004oQ9fAAE", "Name" : "Sean Forbes" } ] } [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 36.291 s [INFO] Finished at: 2017-03-27T15:43:11-06:00 [INFO] Final Memory: 23M/178M [INFO] ------------------------------------------------------------------------

From there you can build any kind of integration with Salesforce data! Note that there is also a REST API for working with the Salesforce metadata if you need to work with the data that describes the data.

Salesforce SOAP Integration with Java

SOAP can be used over any transport protocol so it does not use the semantics of HTTP. Instead it encodes operation information (i.e. create, get, etc) and data types into the payload. This results in a much more verbose protocol which is not often used directly. SOAP also includes the concept of a service descriptor, called a WSDL. This enables client libraries to be generated from that description.

Salesforce generates SOAP client libraries for Java with every new release and publishes them to Maven Central so they can easily be specified as dependencies in Java project builds. You can see the Salesforce SOAP client artifact list and the dependency information on Maven Central. These client libraries have transitive dependencies on the underlying HTTP client and XML libraries that are used under the covers. So you don’t have to work with the protocol, just a type-safe wrapper around it.

First in the project build definition you will see the dependencies on the Salesforce SOAP library. The application is a single file to keep things simple and can be run from an IDE or the command line. It gets the username and password from the command line parameters or asks for them. In the real world, externalize your integration user’s credentials possibly using environment variables. The credentials are then used to login to Salesforce. Once logged in we can invoke a SOAP operation like a query for contacts:

final QueryResult queryResult = partnerConnection.query("SELECT Id, Name FROM Contact");;

This example uses the Partner WSDL which can be safely used against any Salesforce Org because it does not have type-safe representations of Salesforce metadata. You can also use the Enterprise WSDL which does include an Org’s metadata and can thus be used to generate Java types that map to that metadata. Read more about the differences between these two WSDL types in the docs.

Here is what it looks like to run this example from Maven:

~/projects/salesforce-soap-starter $ ./mvnw compile exec:java [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building salesforce-soap-starter 0.0.1-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ salesforce-soap-starter --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory /Volumes/Home/j.ward/projects/salesforce-soap-starter/src/main/resources [INFO] [INFO] --- maven-compiler-plugin:3.6.1:compile (default-compile) @ salesforce-soap-starter --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 1 source file to /Volumes/Home/j.ward/projects/salesforce-soap-starter/target/classes [INFO] [INFO] --- exec-maven-plugin:1.5.0:java (default-cli) @ salesforce-soap-starter --- Salesforce Username: [email protected] Salesforce Password: Querying Contacts XmlObject{name={}records, value=null, children=[XmlObject{name={}type, value=Contact, children=[]}, XmlObject{name={}Id, value=0031a000004oQ9eAAE, children=[]}, XmlObject{name={}Id, value=0031a000004oQ9eAAE, children=[]}, XmlObject{name={}Name, value=Rose Gonzalez, children=[]}]} XmlObject{name={}records, value=null, children=[XmlObject{name={}type, value=Contact, children=[]}, XmlObject{name={}Id, value=0031a000004oQ9fAAE, children=[]}, XmlObject{name={}Id, value=0031a000004oQ9fAAE, children=[]}, XmlObject{name={}Name, value=Sean Forbes, children=[]}]} [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 53.987 s [INFO] Finished at: 2017-03-27T16:31:39-06:00 [INFO] Final Memory: 19M/176M [INFO] ------------------------------------------------------------------------

Now we are reading data from Salesforce via the SOAP API! You can use this as a foundation to build all sorts of integrations on.

As you’ve seen, using the Salesforce REST and SOAP APIs is an easy way to get data into and out of Salesforce. And it is easy to use these APIs from Java. This can be a foundation for all sorts of machine-to-machine integrations. For a deeper dive into the Salesforce APIs, be sure to check out the API Basics Trailhead module, and the additional reading below.

Further Reading

About the Author

On – 12 Apr, 2017 By James Ward

© 2018 P K Global Software Technologies P Ltd