+ Start a Discussion
martin_wumartin_wu 

How to upload files to Content via API using Java client

Hi all,

 

I have tried to find some sample code on developer.force.com for how to upload to Content via API, unsuccessfully unfortunately. I would basically like to automate the batch-upload of a set of files, creating a new item in Content for each file. 

Does anyone have a link with some sample code in Java that I could use to get started?

 

Kind regards,

Martin

 

Best Answer chosen by Admin (Salesforce Developers) 
Pat PattersonPat Patterson

Hi Martin,

Here's some sample code to upload a file to Content via the SOAP API and display the resulting object id - you can check its operation by browsing to https://na1.salesforce.com/<id> - replace na1 with your Salesforce instance.

 

package com.force.example.uploadcontent;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import com.sforce.soap.enterprise.Connector;
import com.sforce.soap.enterprise.EnterpriseConnection;
import com.sforce.soap.enterprise.Error;
import com.sforce.soap.enterprise.SaveResult;
import com.sforce.soap.enterprise.sobject.ContentVersion;
import com.sforce.ws.ConnectorConfig;

// Sample showing how to upload a file to Content
public class UploadContent {
static final String USERNAME = "user@example.com";
static final String PASSWORD = "********";
static EnterpriseConnection connection;

public static void main(String[] args) {
if (args.length < 1) {
System.err.println("Usage: UploadContent path [title] [description]");
System.exit(-1);
}

String path = args[0];
String title = (args.length > 1) ? args[1] : null;
String description = (args.length > 2) ? args[2] : null;

try {
// Read the file
byte[] data = loadFileAsByteArray(path);

// Connect to Salesforce
ConnectorConfig config = new ConnectorConfig();
config.setUsername(USERNAME);
config.setPassword(PASSWORD);
// config.setTraceMessage(true);

connection = Connector.newConnection(config);

// Create an array of ContentVersion with a single member
ContentVersion content = new ContentVersion();
ContentVersion[] contentArray = { content };

// Populate the ContentVersion fields
content.setPathOnClient(path);
if (title != null) {
content.setTitle(title);
}
if (description != null) {
content.setDescription(description);
}
content.setVersionData(data);

// Upload the content to Salesforce
SaveResult[] saveResults = connection.create(contentArray);

// Check the returned results for any errors
for (int i = 0; i < saveResults.length; i++) {
if (saveResults[i].isSuccess()) {
System.out.println(i
+ ". Successfully created record - Id: "
+ saveResults[i].getId());
} else {
Error[] errors = saveResults[i].getErrors();
for (int j = 0; j < errors.length; j++) {
System.out.println("ERROR creating record: "
+ errors[j].getMessage());
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}

// Simplest read of an entire file into a byte array
// Will throw exceptions for file not found etc
private static byte[] loadFileAsByteArray(String path) throws IOException {
File file = new File(path);

InputStream is = new FileInputStream(file);

byte[] data = new byte[(int) file.length()];

is.read(data);

return data;
}
}

The sample uses the Java WSC - you'll need to download wsc-20.jar and generate enterprise.jar as described in the article Introduction to the Force.com Web Services Connector

 

If you run the code in a dev org, you'll need to enable Content for the org and your user:

Setup > Customize > Salesforce CRM Content > Settings - turn on
Setup > Manage Users > Users > (select your user) - turn on 'Salesforce CRM Content User'

You can upload more than one file in the array, but bear in mind the maximum SOAP message size of 50MB.

 

Cheers,


Pat

All Answers

Pat PattersonPat Patterson

Hi Martin,

Here's some sample code to upload a file to Content via the SOAP API and display the resulting object id - you can check its operation by browsing to https://na1.salesforce.com/<id> - replace na1 with your Salesforce instance.

 

package com.force.example.uploadcontent;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import com.sforce.soap.enterprise.Connector;
import com.sforce.soap.enterprise.EnterpriseConnection;
import com.sforce.soap.enterprise.Error;
import com.sforce.soap.enterprise.SaveResult;
import com.sforce.soap.enterprise.sobject.ContentVersion;
import com.sforce.ws.ConnectorConfig;

// Sample showing how to upload a file to Content
public class UploadContent {
static final String USERNAME = "user@example.com";
static final String PASSWORD = "********";
static EnterpriseConnection connection;

public static void main(String[] args) {
if (args.length < 1) {
System.err.println("Usage: UploadContent path [title] [description]");
System.exit(-1);
}

String path = args[0];
String title = (args.length > 1) ? args[1] : null;
String description = (args.length > 2) ? args[2] : null;

try {
// Read the file
byte[] data = loadFileAsByteArray(path);

// Connect to Salesforce
ConnectorConfig config = new ConnectorConfig();
config.setUsername(USERNAME);
config.setPassword(PASSWORD);
// config.setTraceMessage(true);

connection = Connector.newConnection(config);

// Create an array of ContentVersion with a single member
ContentVersion content = new ContentVersion();
ContentVersion[] contentArray = { content };

// Populate the ContentVersion fields
content.setPathOnClient(path);
if (title != null) {
content.setTitle(title);
}
if (description != null) {
content.setDescription(description);
}
content.setVersionData(data);

// Upload the content to Salesforce
SaveResult[] saveResults = connection.create(contentArray);

// Check the returned results for any errors
for (int i = 0; i < saveResults.length; i++) {
if (saveResults[i].isSuccess()) {
System.out.println(i
+ ". Successfully created record - Id: "
+ saveResults[i].getId());
} else {
Error[] errors = saveResults[i].getErrors();
for (int j = 0; j < errors.length; j++) {
System.out.println("ERROR creating record: "
+ errors[j].getMessage());
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}

// Simplest read of an entire file into a byte array
// Will throw exceptions for file not found etc
private static byte[] loadFileAsByteArray(String path) throws IOException {
File file = new File(path);

InputStream is = new FileInputStream(file);

byte[] data = new byte[(int) file.length()];

is.read(data);

return data;
}
}

The sample uses the Java WSC - you'll need to download wsc-20.jar and generate enterprise.jar as described in the article Introduction to the Force.com Web Services Connector

 

If you run the code in a dev org, you'll need to enable Content for the org and your user:

Setup > Customize > Salesforce CRM Content > Settings - turn on
Setup > Manage Users > Users > (select your user) - turn on 'Salesforce CRM Content User'

You can upload more than one file in the array, but bear in mind the maximum SOAP message size of 50MB.

 

Cheers,


Pat

This was selected as the best answer
Pat PattersonPat Patterson

...and I just noticed that you'd posted the question in the REST forum, but I supplied a SOAP answer... The perils of following the discussion boards via RSS!

 

Let me see if I can recast my solution in REST.

Pat PattersonPat Patterson

Here is equivalent functionality in Java using the REST API - the loadFileAsByteArray() method is the same as in the previous example.

 

 

    private String uploadContent(String path, String title, String description,
            String instanceUrl, String accessToken, PrintWriter writer)
            throws JSONException, IOException {
        // Read the file
        byte[] data = loadFileAsByteArray(path);

        HttpClient httpclient = new HttpClient();

        JSONObject content = new JSONObject();

        content.put("PathOnClient", path);
        if (title != null) {
            content.put("Title", title);
        }
        if (description != null) {
            content.put("Description", description);
        }
        content.put("VersionData", new String(Base64.encodeBase64(data)));

        PostMethod post = new PostMethod(instanceUrl
                + "/services/data/v21.0/sobjects/ContentVersion/");

        post.setRequestHeader("Authorization", "OAuth " + accessToken);
        post.setRequestEntity(new StringRequestEntity(content.toString(),
                "application/json", null));

        String contentId = null;
        try {
            httpclient.executeMethod(post);

            if (post.getStatusCode() == HttpStatus.SC_CREATED) {
                JSONObject response = new JSONObject(new JSONTokener(
                        new InputStreamReader(
                                post.getResponseBodyAsStream())));
                if (response.getBoolean("success")) {
                    contentId = response.getString("id");
                }
            }
        } finally {
            post.releaseConnection();
        }

        return contentId;
    }

I've used Apache HttpClient and the JSON.org Java library - you may need to adapt the code slightly to match your environment, but it shows the general approach.

 

martin_wumartin_wu

This is brillient, thanks so much, Pat. The code for the SOAP access is perfectly. I don't mind which protocol I use, as long as it works.

Thanks a million for your help. I'll give it a go now.

 

Cheers,

Martin

 

Pat PattersonPat Patterson

You're welcome, Martin. Just to close the loop - here's the link to the docs - there's a bit more detail there.

Chirag MehtaChirag Mehta

Thanks Pat for the REST API version. How do we set custom fields of Content? I tried to set following and then the contentversion insert fails. What wrong am I doing here?

 

content.put("Account__c", "0019000000Gtw0IAAR");

 

Pat PattersonPat Patterson

What is the error on the insert? I would double check the field name - maybe it's AccountId__c?

Chirag MehtaChirag Mehta
Yes Pat on API name I'm 100% sure :)

And the response is 400 / Bad request.
Pat PattersonPat Patterson

What is the body of the response? That usually carries more data.

Chirag MehtaChirag Mehta
oh here I see :
[{"fields":[],"message":"You cannot set custom fields or tags on a document published into a personal library. Fields set: Account","errorCode":"FIELD_INTEGRITY_EXCEPTION"}]
Chirag MehtaChirag Mehta
I used non personal library and it worked.

Thank you once again Pat!

content.put("FirstPublishLocationId", "05890000000Hdl5AAC");
content.put("Account__c", "0019000000Gtw0IAAR");
JyotiGoyalJyotiGoyal
Hi Pat,

Can you help me in Rest API file creation code?
I am creating files with size more than 500mb. I got java.lang.OutOfMemoryError: Java heap space error. I can not increase virtual memory size. Can I send file in chunks to salesforce or some other way to avoid this situation?

Please help me in this.

Thanks,
neelam mooreneelam moore
HI Pat,. 

I tried using your piece of code but i cannnot transfer any file which is above 52 MB. I thought the REST api file transfer limit is 2GB but it gives this error:

  "message" : "; nested exception is: \n\tcommon.exception.ApiException: Maximum size of request reached. Maximum size of request is 52428800 bytes.",
  "errorCode" : "JSON_PARSER_ERROR"

I tried also using  use a multipart message using MultipartRequestEntity but that results in this error:

  "message" : "multipart form upload failed because field 'json' exceeds max length 10485760",
  "errorCode" : "INVALID_MULTIPART_REQUEST"

Please let me know if there is a workaroud for this size issue.

Thanks

 
Aaron Bauman 15Aaron Bauman 15
The link http://www.salesforce.com/docs/developer/cookbook/index_Left.htm#CSHID=publish_documents.htm|StartTopic=Content%2Fpublish_documents.htm|SkinName=webhelp is broken, and I can't find any backup documentation about how to create a new ContentDocument using rest API.

Loads of docs about how to create a ContentVersion.

Please update.
vishakha Rajpalvishakha Rajpal
Hi All,

Does anyone have a link with some sample code in .NET(c#) that I could use to get started?

Thanks
Vishakha