Using the Core API in Java

The Core API is based on HTTP and OAuth and provides low-level calls to access and manipulate a user's Dropbox account.

If you want to follow along, first register a new app on the App Console. You'll need the app key to access the Core API. Then install the Java SDK and you'll be ready to go.

Authenticating your app

The Core API uses OAuth v2, but the Java SDK will take care of most of it so you don't have to start from scratch.

You'll need to provide your app key and secret to the new DbxWebAuthNoRedirect object.

// Include the Dropbox SDK.
import com.dropbox.core.*;
import java.io.*;
import java.util.Locale;

public class Main {
    public static void main(String[] args) throws IOException, DbxException {
        // Get your app key and secret from the Dropbox developers website.
        final String APP_KEY = "INSERT_APP_KEY";
        final String APP_SECRET = "INSERT_APP_SECRET";

        DbxAppInfo appInfo = new DbxAppInfo(APP_KEY, APP_SECRET);

        DbxRequestConfig config = new DbxRequestConfig(
            "JavaTutorial/1.0", Locale.getDefault().toString());
        DbxWebAuthNoRedirect webAuth = new DbxWebAuthNoRedirect(config, appInfo);

Now we're all set to start the OAuth flow. The OAuth flow has two parts:

  1. Ask the user to authorize linking your app to their Dropbox account.
  2. Once authorized, exchange the received authorization code for an access token, which will be used for calling the Core API.

We'll start by using the DbxWebAuthNoRedirect object to generate an authorization URL with the start method.

String authorizeUrl = webAuth.start()

With the authorization URL in hand, we can now ask the user to authorize your app. To avoid the hassle of setting up a web server in this tutorial, we're just printing the URL and asking the user to press the Enter key to confirm that they've authorized your app. However, in real-world apps, you'll want to automatically send the user to the authorization URL and pass in a callback URL so that the user is seamlessly redirected back to your app after pressing a button.

// Have the user sign in and authorize your app.
String authorizeUrl = webAuth.start();
System.out.println("1. Go to: " + authorizeUrl);
System.out.println("2. Click \"Allow\" (you might have to log in first)");
System.out.println("3. Copy the authorization code.");
String code = new BufferedReader(new InputStreamReader(System.in)).readLine().trim();

Once the user has delivered the authorization code to our app, we can exchange that code for an access token via finish:

DbxAuthFinish authFinish = webAuth.finish(code);
String accessToken = authFinish.accessToken;

The access token is all you'll need to make API requests on behalf of this user, so you should store it away for safe-keeping (even though we don't for this tutorial). By storing the access token, you won't need to go through these steps again unless the user reinstalls your app or revokes access via the Dropbox website.

Now that the hard part is done, all we need to do to authorize our API calls is to to pass the access token to DbxClient. To test that we have got access to the Core API, let's try calling getAccountInfo, which will return a dictionary with information about the user's linked account:

DbxClient client = new DbxClient(config, accessToken);
System.out.println("Linked account: " + client.getAccountInfo().displayName);

If you've made it this far, you now have a simple app that uses the Core API to link to a Dropbox account and make an API call to retrieve account info. Next, we'll upload a file to Dropbox, get its metadata, and then download it back to our app.

Uploading files

Let's say we're building a text editing app and we want to use it to save your latest magnum opus to Dropbox. Let's browse the methods in the DbxClient documentation to see which one will do that for us. This page lists all the methods supported in the SDK. If you scroll down, you'll find uploadFile.

uploadFile takes a path pointing to where we want the file on our Dropbox, and then a file-like object or string to be uploaded there. For this example, let's upload a local copy of working-draft.txt:

File inputFile = new File("working-draft.txt");
FileInputStream inputStream = new FileInputStream(inputFile);
try {
    DbxEntry.File uploadedFile = client.uploadFile("/magnum-opus.txt",
        DbxWriteMode.add(), inputFile.length(), inputStream);
    System.out.println("Uploaded: " + uploadedFile.toString());
} finally {
    inputStream.close();
}

If all goes well, the data in your local working-draft.txt will now be in the root of your app folder (or Dropbox folder, depending on your app's access type). The variable uploadedFile will contain the metadata of the newly uploaded file. It will look something like this:

File {
  "/magnum-opus.txt"
  iconName = "page_white_text"
  mightHaveThumbnail = false
  numBytes = 14
  humanSize = "14 bytes"
  lastModified = "2013/08/23 02:25:49 UTC"
  clientMtime = "2013/08/23 02:25:49 UTC"
  rev = "1312e120be"
}

Listing folders

If you peruse the various entries in the metadata above, you'll get a good sense for all info we can gather from the file. You can get this info for an entire folder by using the getMetadataWithChildren call.

DbxEntry.WithChildren listing = client.getMetadataWithChildren("/");
System.out.println("Files in the root path:");
for (DbxEntry child : listing.children) {
    System.out.println("	" + child.name + ": " + child.toString());
}

The returned object will list the files and folders in the given path, including their metadata. Enumerating them, you'll see something like this:

Files in the root path:
    magnum-opus.txt: File("/magnum-opus.txt", iconName="page_white_text",
        mightHaveThumbnail=false, numBytes=14, humanSize="14 bytes",
        lastModified="2013/08/23 02:25:49 UTC", clientMtime="2013/08/23 02:25:49 UTC",
        rev="1312e120be")

In the example above, the app folder root contains the file we just uploaded named magnum-opus.txt. You'll see various bits of information such as the exact location of the file, the file size, last modified date, and more.

Downloading files

Some time has passed and you're ready to start editing that magnum opus of yours again. We'll need the getFile method to download the file.

FileOutputStream outputStream = new FileOutputStream("magnum-opus.txt");
try {
    DbxEntry.File downloadedFile = client.getFile("/magnum-opus.txt", null,
        outputStream);
    System.out.println("Metadata: " + downloadedFile.toString());
} finally {
    outputStream.close();
}

In addition to writing the file to your output stream, the method also returns the file's metadata at its current revision. Every time a change is made to the file, the rev field of the file's metadata changes as well. By saving the revision when you download the file, you'll be able to tell if that file has been updated by another computer or device and choose to download the newer revision of that file.

The complete code

For those keeping score at home, here's the full source to this guide. Make sure to create a working-draft.txt file to get it to work fully. Also remember to insert your app key, app secret, and access type.

// Include the Dropbox SDK.
import com.dropbox.core.*;
import java.io.*;
import java.util.Locale;

public class Main {
    public static void main(String[] args) throws IOException, DbxException {
        // Get your app key and secret from the Dropbox developers website.
        final String APP_KEY = "INSERT_APP_KEY";
        final String APP_SECRET = "INSERT_APP_SECRET";

        DbxAppInfo appInfo = new DbxAppInfo(APP_KEY, APP_SECRET);

        DbxRequestConfig config = new DbxRequestConfig("JavaTutorial/1.0",
            Locale.getDefault().toString());
        DbxWebAuthNoRedirect webAuth = new DbxWebAuthNoRedirect(config, appInfo);

        // Have the user sign in and authorize your app.
        String authorizeUrl = webAuth.start();
        System.out.println("1. Go to: " + authorizeUrl);
        System.out.println("2. Click \"Allow\" (you might have to log in first)");
        System.out.println("3. Copy the authorization code.");
        String code = new BufferedReader(new InputStreamReader(System.in)).readLine().trim();

        // This will fail if the user enters an invalid authorization code.
        DbxAuthFinish authFinish = webAuth.finish(code);
        String accessToken = authFinish.accessToken;

        DbxClient client = new DbxClient(config, accessToken);

        System.out.println("Linked account: " + client.getAccountInfo().displayName);

        File inputFile = new File("working-draft.txt");
        FileInputStream inputStream = new FileInputStream(inputFile);
        try {
            DbxEntry.File uploadedFile = client.uploadFile("/magnum-opus.txt",
                DbxWriteMode.add(), inputFile.length(), inputStream);
            System.out.println("Uploaded: " + uploadedFile.toString());
        } finally {
            inputStream.close();
        }

        DbxEntry.WithChildren listing = client.getMetadataWithChildren("/");
        System.out.println("Files in the root path:");
        for (DbxEntry child : listing.children) {
            System.out.println("	" + child.name + ": " + child.toString());
        }

        FileOutputStream outputStream = new FileOutputStream("magnum-opus.txt");
        try {
            DbxEntry.File downloadedFile = client.getFile("/magnum-opus.txt", null,
                outputStream);
            System.out.println("Metadata: " + downloadedFile.toString());
        } finally {
            outputStream.close();
        }
    }
}