[AWS SDK for Java] S3からファイルをダウンロードするアプリケーションの作成

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは。クラスメソッドの稲毛です。

仕事ではクライアントサイドの開発に携わる事の多かった私ですが、この度AWSに触れる機会がありましたのでその備忘録として残そうと思い本記事を執筆しました。これからAWSを使ってみようという方にとって有益な情報となれば幸いです。

今回はS3からファイルをダウンロードするアプリケーションをJavaで作成しました。

開発環境

開発環境にはEclipseを用います。
後述するAWS Toolkit for Eclipseでは、Eclipse IDE for Java EE Developers 3.7が推奨されているので、Eclipse 3.7 Indigo Pleiades All in OneのJavaパッケージを用意しました。

AWS Toolkit for Eclipseのインストール

AWS Toolkit for EclipseをEclipseへインストールします。

ヘルプメニューから「新規ソフトウェアのインストール...」を選択します。

001

作業対象欄に下記のURLを入力し確定します。

  • http://aws.amazon.com/jp/eclipse/

002

暫く待つと一覧にプラグインが表示されるので、「AWS for Android」以外をチェックして次へボタンを押下します。

003

インストール詳細を確認し、次へボタンを押下します。

004

使用条件の条項に同意したらラジオボタンを選択し、完了ボタンを押下します。

005

ソフトウェアのインストール中を表すダイアログが表示されます。

006

下図の警告が表示された場合はOKボタンを押下します。

007

Eclipseの再起動を促すダイアログが出たら今すぐ再始動ボタンを押下してインストールの完了です。

008

Eclipse再起動時にAWSアカウントの入力を求められるので入力し完了ボタンを押下します。AWSアカウントを持っていない場合は、アカウントを取得し設定します。

009

AWS Java Projectの作成

Toolkitを利用するとAWS用のJavaプロジェクトを容易に作成することが可能です。

ツールバー上のAWSアイコンのメニューから「New AWS Java Project...」を選択します。

011

プロジェクト名を入力し、生成するサンプルアプリケーションを選択します。今回はS3操作なので「Amazon S3 Sample」を選択し、完了ボタンを押下します。

012

下図のようにJavaプロジェクトが作成されました。

013

プロジェクトフォルダ内部の構成は下記の通りです。

S3Sample
 ├─ src
 │   ├─ (デフォルト・パッケージ)
 │   │   └─ S3Sample.java・・・・・・・・サンプルとして生成されたクラスです。
 │   └─ AwsCredentials.properties・・・・AWSへ接続する為のアカウント情報が格納されたpropertiesファイルです。
 ├─ JRE システム・ライブラリー ・・・・・標準Javaライブラリです。
 └─ AWS SDK for Java ・・・・・・・・・・AWS SDKライブラリです。

ダウンロード処理の実装

サンプルとして生成されたS3Sample.javaには、一連のS3を操作する処理が記述されています。

  1. バケットの新規作成
  2. バケット一覧の取得
  3. バケットへのファイルアップロード
  4. バケットからのファイルダウンロード
  5. バケット内オブジェクト一覧の取得
  6. バケット内オブジェクトの削除
  7. バケットの削除

この内の「4. バケットからのファイルダウンロード」を利用すれば簡単に実現出来てしまいますね。

S3Sample.java
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.auth.ClasspathPropertiesFileCredentialsProvider;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.S3Object;

public class S3Sample {

    public static void main(String[] args) throws IOException {
        AmazonS3 s3 = new AmazonS3Client(new ClasspathPropertiesFileCredentialsProvider());
        Region northEast1 = Region.getRegion(Regions.AP_NORTHEAST_1);
        s3.setRegion(northEast1);

        String bucketName = "inage-test-bucket";
        String key = "test.csv";

        S3Object object = null;
        try {
            object = s3.getObject(new GetObjectRequest(bucketName, key));
        } catch (AmazonServiceException ase) {
            System.out.println("Caught an AmazonServiceException, which means your request made it "
                    + "to Amazon S3, but was rejected with an error response for some reason.");
            System.out.println("Error Message:    " + ase.getMessage());
            System.out.println("HTTP Status Code: " + ase.getStatusCode());
            System.out.println("AWS Error Code:   " + ase.getErrorCode());
            System.out.println("Error Type:       " + ase.getErrorType());
            System.out.println("Request ID:       " + ase.getRequestId());
        } catch (AmazonClientException ace) {
            System.out.println("Caught an AmazonClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with S3, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message: " + ace.getMessage());
        }

        if (object == null) return;

        try (
                BufferedInputStream bis = new BufferedInputStream(object.getObjectContent());
                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(object.getKey()));
            ) {
            int data = bis.read();
            while (-1 < data) {
                bos.write(data);
                data = bis.read();
            }
        }
    }

}
[/java]
<p>重要な箇所は以下の三点です。</p>
<dl>
<dt>19~21行目</dt>
<dd>S3を操作する為のオブジェクトを取得します。<br>
AWSのサインイン情報からAmazonS3オブジェクトを生成しリージョンを設定しています。</dd>

AmazonS3 s3 = new AmazonS3Client(new ClasspathPropertiesFileCredentialsProvider());
Region northEast1 = Region.getRegion(Regions.AP_NORTHEAST_1);
s3.setRegion(northEast1);
28行目
バケット名およびオブジェクトキー(ファイル名)からS3Objectを取得しています。
object = s3.getObject(new GetObjectRequest(bucketName, key));
47行目
S3Objectからストリームを取得します。
BufferedInputStream bis = new BufferedInputStream(object.getObjectContent());

後は入力ストリームをファイル出力すればダウンロード完了です。

まとめ

初めてAWS SDKを利用した感想は、「必要十分な情報はAWS Toolkitが提供してくれそう!簡単そうだ!」というものでした。もちろんこれだけでAWS SDKの利用法がマスターできるとは思いませんが、Toolkitでサンプルアプリケーションを生成して試す事でSDKの操作方法を学んでいけそうです。まだまだAWSビギナーですが、これらの優秀なツールを使ってさらに理解を深めていけたらと考えています。