Status Code 303 - See Other

サーバサイド、iOS・アンドロイドアプリ、インフラレベルの話まで幅広くやってます。情報の誤りや指摘・意見などは自由にどうぞ。

Dropbox API を使ってみる

概要

普段何気なく使っているツールに、Dropbox がある。

このツールは、様々なデバイス間のファイル変更を自動でマージしてくれる他、
リビジョンも保存するため、間違って上書きした場合などに、前回のファイルを復帰することができる。
また、Dropbox は記録領域をアプリ動作環境以外でも共有できるため、使用ユーザはその情報をどこからでも自由に参照できる。

今回は、このDropbox API を使って、Dropbox の操作をプログラムの一部に組み込む。

導入

本家にチュートリアルがあるため、手順はそれほど難しくない。
しかし、英語なので得意でない人は、覚悟がいるかも。(それほど難しくない)
Dropbox - Developers

ライブラリ導入

API は、バージョン1, 2 の2つ存在する。新しい方の v2 を今回は用いる。
Maven 使っている人は、以下を pom.xml に追加する。

<dependency>
    <groupId>com.dropbox.core</groupId>
    <artifactId>dropbox-core-sdk</artifactId>
    <version>2.0-beta-5</version>
</dependency>

(上記はDropbox 本家の内容を引用。2016/3/3 から、正式版ライブラリ 2.0.0 がリリースされてます。)

ビルドパスだけで設定したい人は、Maven レポジトリ(Maven Repository: Search/Browse/Explore)
から以下の jarファイル をダウンロードしてビルドパスに加える。

API ライブラリ
JSON処理系ライブラリ
  • jackson-core-2.7.1.jar
  • jackson-annotations-2.5.4.jar
  • jackson-databind-2.5.4.jar
その他依存ライブラリ
  • animal-sniffer-annotations-1.10.jar
  • okhttp-2.5.0.jar
  • okio-1.6.0.jar

app登録

Dropbox のアカウントがない人は、まず作成。
本日時点では、メールアドレスを使って無料で作成できる。

次に、Dropbox API を使用するアプリの登録する。
Dropbox の Developer サイト(Dropbox - Developers) のメニューから【My apps】を選択。
右上のボタン【Create app】からアプリ登録をする。内容はそれほど難しくないため設定内容は割愛。

設定ファイル

プログラムから Dropbox API を使用するのに必要な情報は次の2つ。

  • アプリ名
  • トークン文字列 (アプリ詳細の settings タブ /OAuth 2 /Generated access token /【Generate】ボタンを押して作成)

なお、これらがあると Dropbox API をどこでも使用できるため、情報管理には気を使うこと。
この部分を dropbox.properties に記述。

dropbox.app.name = 
dropbox.access.token = 

参考:プロパティファイルの使用方法 - Status Code 303 - See Other

コード実装

ほぼ機能として作り込まれているため、そのままロジックに記述。今回の実装内容と動きは以下の通り。

  1. API と通信するクライアント作成
  2. Dropbox の現在の最大容量・使用量の表示
  3. フォルダ作成 (+フォルダ内にファイルが存在しないか確認)
  4. ファイルをアップロード (+フォルダ内にファイルが作られたこと確認)
  5. 10秒間スレッドスリープ (本来不要。リビジョンの更新日時を分かりやすくするため)
  6. 別ファイルを同名で上書きアップロード (+フォルダ内にあるアップロードファイルは1つであること確認)
  7. アップロードしたファイルのリビジョン表示 (+リビジョンが複数ある(サイズ/更新時間が異なる)ことを確認)
  8. アップロードしたファイルをダウンロード
  9. 最初に作成したフォルダの削除
package api.dropbox;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

import com.dropbox.core.DbxException;
import com.dropbox.core.DbxRequestConfig;
import com.dropbox.core.v2.DbxClientV2;
import com.dropbox.core.v2.files.FileMetadata;
import com.dropbox.core.v2.files.Metadata;
import com.dropbox.core.v2.files.WriteMode;

import resources.properties.Property;

public class Main {

	public static void main(String[] args) throws DbxException, IOException, InterruptedException {
		Property property = new Property("dropbox");
		DbxRequestConfig config = new DbxRequestConfig(property.getString("dropbox.app.name"), "ja_JP");
		DbxClientV2 client = new DbxClientV2(config, property.getString("dropbox.access.token"));

		
		System.out.println("Capacity: "
				+ client.users().getSpaceUsage().getAllocation().getIndividualValue().getAllocated() / 1024 / 1024 + " MB");
		System.out.println("Usage: " + client.users().getSpaceUsage().getUsed() / 1024 / 1024 + " MB");
		
		System.out.println("Create Folder /test ---------");
		client.files().createFolder("/test"); // 既に存在していると例外発生
		System.out.println("Show file list under /test ---------");
		for (Metadata metadata : client.files().listFolder("/test").getEntries()) {
			System.out.println(metadata.getName());
		}
		System.out.println("Upload /test/sample.jar ---------");
		FileInputStream fileStream = new FileInputStream(new File("./lib/dropbox/okhttp-2.5.0.jar"));
		client.files().uploadBuilder("/test/sample.jar").withMode(WriteMode.OVERWRITE).uploadAndFinish(fileStream);
		System.out.println("Show file list under /test ---------");
		for (Metadata metadata : client.files().listFolder("/test").getEntries()) {
			System.out.println(metadata.getName());
		}
		System.out.println("Sleep 10 seconds......please wait a moment.");
		Thread.sleep(10000);

		System.out.println("Overwrite /test/sample.jar ---------");
		FileInputStream fileStream2 = new FileInputStream(new File("./lib/dropbox/okio-1.6.0.jar"));
		client.files().uploadBuilder("/test/sample.jar").withMode(WriteMode.OVERWRITE).uploadAndFinish(fileStream2);
		System.out.println("Show file list under /test ---------");
		for (Metadata metadata : client.files().listFolder("/test").getEntries()) {
			System.out.println(metadata.getName());
		}
		
		System.out.println("Show file list under /test ---------");
		for (Metadata metadata : client.files().listFolder("/test").getEntries()) {
			System.out.println(metadata.getName());
		}

		System.out.println("Show revision list about /test/sample.jar ---------");
		List<FileMetadata> revisions = client.files().listRevisions("/test/sample.jar").getEntries();
		for (FileMetadata filemetadata : revisions) {
			System.out.println("Name:" + filemetadata.getName() + "\tSize:" + filemetadata.getSize() + "\tDate:" + filemetadata.getClientModified());
		}

		System.out.println("Download sample.jar into THIS project under /lib/sample.jar ---------");
		FileOutputStream outputStream = new FileOutputStream(new File("./lib/dropbox/sample.jar"));
		client.files().download("/test/sample.jar").download(outputStream);
		
		System.out.println("Remove /test ---------");
		client.files().delete("/test"); //削除対象がないと例外発生
	}
}

これによって、次のような出力が表示される。

Capacity: 3072 MB
Usage: 3019 MB
Create Folder /test ---------
Show file list under /test ---------
Upload /test/sample.jar ---------
Show file list under /test ---------
sample.jar
Sleep 10 seconds......please wait a moment.
Overwrite /test/sample.jar ---------
Show file list under /test ---------
sample.jar
Show file list under /test ---------
sample.jar
Show revision list about /test/sample.jar ---------
Name:sample.jar	Size:65928	Date:Sat Mar 05 01:30:35 JST 2016
Name:sample.jar	Size:317886	Date:Sat Mar 05 01:30:23 JST 2016
Download sample.jar into THIS project under /lib/sample.jar ---------
Remove /test ---------

それに呼応して、Dropboxを起動していると、「test を追加しました」「sample.jar を作成しました」
「sample.jar を上書きしました」「2つのファイルを削除しました」などのメッセージが表示され、
標準出力をしなくても、Java アプリから Dropbox を操作できたことを確認できる。