ようへい

2018年12月5日水曜日

GAE/J の環境から、 Dropbox にファイルをアップロードする

Google App Engine / Java8 の環境で、ファイルをアップロードされた場合、アップロードしたファイルの置き場所をどうしようかと悩んでいた。
すると、Dropbox の API があるようだったので使用してみることにした。
なんとなく GAE の環境に対応していそう。
Dropbox Core SDK for Java 6+
https://github.com/dropbox/dropbox-sdk-java とりあえず、以下でアクセストークンを作成。
Generate an access token for your own account
https://blogs.dropbox.com/developers/2014/05/generate-an-access-token-for-your-own-account/ チュートリアルにあるように、以下のように実装。
DbxRequestConfig config = DbxRequestConfig.newBuilder(SystemProperty.applicationId.get()).build();
DbxClientV2 client = new DbxClientV2(config, <<DROPBOX_ACCESS_TOKEN>>);
client.files().uploadBuilder("/GAE/" + fileName).withMode(WriteMode.OVERWRITE)
    .uploadAndFinish(fileStream);
とりあえずデプロイしてGAE上で実行。
すると案の定エラーが。
error: com.dropbox.core.NetworkIOException: content.dropboxapi.com (Logger.java:58)
 at com.dropbox.core.v2.DbxRawClientV2.uploadStyle(DbxRawClientV2.java:259)
 at com.dropbox.core.v2.files.DbxUserFilesRequests.upload(DbxUserFilesRequests.java:2985)
 at com.dropbox.core.v2.files.UploadBuilder.start(UploadBuilder.java:154)
 at com.dropbox.core.v2.files.UploadBuilder.start(UploadBuilder.java:20)
 at com.dropbox.core.v2.DbxUploadStyleBuilder.uploadAndFinish(DbxUploadStyleBuilder.java:92)
GAEで開発してる人ならピンと来るはず。
GAE/Java 8では外部にアクセスする際に使用する、Javaネイティブの java.net.URL.openConnection などが無効になり、URLFetchServiceFactory を使う必要がある。
どうやらホスト名が引けず、エラーになっているようなので、何かしら GAE 用の処理を加えないと使えなさそう。
GitHub で、検索をかけるとソース上に使用方法が書いてあった。
dropbox-sdk-java/src/main/java/com/dropbox/core/http/GoogleAppEngineRequestor.java
https://github.com/dropbox/dropbox-sdk-java/blob/aa70590b492bc79a47c6eaf5bc667206ab51bfdd/src/main/java/com/dropbox/core/http/GoogleAppEngineRequestor.java#L25
/**
 * {@link HttpRequestor} implementation that uses Google App Engine URL fetch service.
 * You can only use this if your project includes the App Engine libraries.
 *
 * <p> If your app runs in Google App Engine, it is strongly recommended to use this Requestor to
 * ensure certificate validation is performed on all requests.
 *
 * <p> To use this, pass an instance to the {@link com.dropbox.core.DbxRequestConfig} constructor:
 *
 * <pre>
 *     DbxRequestConfig config = DbxRequestConfig.newBuilder("MyAppEngineApp/1.0")
 *         .withHttpRequestor(new GoogleAppEngineRequestor())
 *         .build();
 *
 *     String accessToken = ...;
 *     DbxClientV2 client = new DbxClientV2(config, accessToken);
 * </pre>
 */
なるほど。
.withHttpRequestor(new GoogleAppEngineRequestor()) が必要らしい。
これを加えて、先ほどのコードを修正。
DbxRequestConfig config = DbxRequestConfig.newBuilder(SystemProperty.applicationId.get())
        .withHttpRequestor(new GoogleAppEngineRequestor()).build();
DbxClientV2 client = new DbxClientV2(config, <<DROPBOX_ACCESS_TOKEN>>);
client.files().uploadBuilder("/GAE/" + fileName).withMode(WriteMode.OVERWRITE)
        .uploadAndFinish(fileStream);
無事アップロードできるようになりました。
関連記事

0 件のコメント:

コメントを投稿