Spring BootでAzure Blob Storageを操作する

Spring BootでAzure Blob Storageを操作する

Spring BootにおけるAzure Blob Storageの操作にはspring-cloud-azure-starter-storage-blobを使用する。

spring-cloud-azure-starter-storage-blobを使用するには、併せてazure-spring-boot-bomを追加する必要がある。

具体的には、下記を build.gradle に追記する。

dependencies {
    // Azure Blob Storage
    implementation 'com.azure.spring:spring-cloud-azure-starter-storage-blob'
}

dependencyManagement {
    imports {
        mavenBom "com.azure.spring:azure-spring-boot-bom:${azure_spring_boot_bom_version}"
    }
}

spring-cloud-azure-starter-storage-blobのバージョンは gradle.properties に記述する。

以下のように定義する。

azure_spring_boot_bom_version=4.4.0

接続先情報を設定する

application.yml にストレージアカウント名・アカウントキー・エンドポイント名を設定する。

以下の記述例では設定値を直接application.ymlに記述しているが、実際には環境変数から取得するのが望ましい。

# Azure Blob Storageの設定
azure:
    storage:
        accountName: samplestorage
        accountKey: Xx1Xxxxx0xO9XXXXx4x/0xX0xXxX+==
        blob-endpoint: https://samplestorage.blob.core.windows.net/

使用方法

使用したいクラスでBlobServiceClientをDIする。 BlobServiceClientはAzure StorageリソースとBLOB コンテナを操作を行うクライアントである。

コンストラクタインジェクションをする例を示す。

import org.springframework.stereotype.Service;

import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobServiceClientBuilder;

@Service
public class SampleServiceImpl implements SampleService {

    /** BlobServiceClient */
    private BlobServiceClient client;

    /**
     * コンストラクタ
     */
    public SampleServiceImpl(BlobServiceClientBuilder builder) {
        this.client = builder.buildClient();
    }
}

コンテナの作成

「sample」コンテナを作成する例を示す。

  1. BlobServiceClientのcreateBlobContainer(Stirng)メソッドを呼び出す。 引数にコンテナ名を指定する。
    戻り値としてBlobContainerClientが得られる。 BlobContainerClientはコンテナの操作を行うクライアントである。
    既に同名のコンテナが存在していた場合はBlobStorageExceptionがスローされる。
import org.springframework.stereotype.Service;

import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobServiceClientBuilder;

@Service
public class SampleServiceImpl implements SampleService {

    /** BlobServiceClient */
    private BlobServiceClient client;

    /**
     * コンストラクタ
     */
    public SampleServiceImpl(BlobServiceClientBuilder builder) {
        this.client = builder.buildClient();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void doSomething() {
        String containerName = "sample";
        BlobContainerClient containerClient = client.createBlobContainer(containerName);
    }
}

BlobContainerClientを先に取得してからコンテナを作成することもできる。

  1. BlobServiceClientのgetBlobContainerClient(String)メソッドを呼び出し、作成するコンテナのBlobContainerClientを取得する。
  2. BlobContainerClientのcreate()メソッドを呼ぶ。

既に同名のコンテナが存在していた場合はBlobStorageExceptionがスローされる。

import org.springframework.stereotype.Service;

import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobServiceClientBuilder;

@Service
public class SampleServiceImpl implements SampleService {

    /** BlobServiceClient */
    private BlobServiceClient client;

    /**
     * コンストラクタ
     */
    public SampleServiceImpl(BlobServiceClientBuilder builder) {
        this.client = builder.buildClient();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void doSomething() {
        String containerName = "sample";
        BlobContainerClient containerClient = client.getBlobContainerClient(containerName);
        containerClient.create();
    }
}

コンテナの削除(コンテナ内のファイルも削除される)

「sample」コンテナを削除する例を示す。

  1. BlobServiceClientのdeleteBlobContainer(Stirng)メソッドを呼び出す。 引数にコンテナ名を指定する。
import org.springframework.stereotype.Service;

import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobServiceClientBuilder;

@Service
public class SampleServiceImpl implements SampleService {

    /** BlobServiceClient */
    private BlobServiceClient client;

    /**
     * コンストラクタ
     */
    public SampleServiceImpl(BlobServiceClientBuilder builder) {
        this.client = builder.buildClient();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void doSomething() {
        String containerName = "sample";
        client.deleteBlobContainer(containerName);
    }
}

BlobContainerClientからコンテナを削除することもできる。

  1. BlobServiceClientのgetBlobContainerClient(String)メソッドを呼び出し、作成するコンテナのBlobContainerClientを取得する。
  2. BlobContainerClientのdelete()メソッドを呼ぶ。
import org.springframework.stereotype.Service;

import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobServiceClientBuilder;

@Service
public class SampleServiceImpl implements SampleService {

    /** BlobServiceClient */
    private BlobServiceClient client;

    /**
     * コンストラクタ
     */
    public SampleServiceImpl(BlobServiceClientBuilder builder) {
        this.client = builder.buildClient();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void doSomething() {
        String containerName = "sample";
        BlobContainerClient containerClient = client.getBlobContainerClient(containerName);
        containerClient.delete();
    }
}

コンテナの存在チェック

java」コンテナのみ存在している場合のチェック例を示す。

  1. 存在チェックをしたいコンテナのBlobContainerClientを取得する。
  2. BlobContainerClientのexists()メソッドを呼ぶ。
import org.springframework.stereotype.Service;

import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobServiceClientBuilder;

@Service
public class SampleServiceImpl implements SampleService {

    /** BlobServiceClient */
    private BlobServiceClient client;

    /**
     * コンストラクタ
     */
    public SampleServiceImpl(BlobServiceClientBuilder builder) {
        this.client = builder.buildClient();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void doSomething() {
        BlobContainerClient containerClient = client.getBlobContainerClient("java");
        boolean exists = containerClient.exists(); // true
        BlobContainerClient containerClient2 = client.getBlobContainerClient("sample");
        boolean exists2 = containerClient2.exists(); // false
    }
}

コンテナ内のBlobファイルの一覧表示

java」コンテナ内のBlobファイル一覧を取得する例を示す。

  1. Blobファイルの一覧を確認したいコンテナのBlobContainerClientを取得する。
  2. BlobContainerClientのlistBlobs()メソッドを呼ぶ。
import org.springframework.stereotype.Service;

import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobServiceClientBuilder;
import com.azure.storage.blob.models.BlobItem;

@Service
public class SampleServiceImpl implements SampleService {

    /** BlobServiceClient */
    private BlobServiceClient client;

    /**
     * コンストラクタ
     */
    public SampleServiceImpl(BlobServiceClientBuilder builder) {
        this.client = builder.buildClient();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void doSomething() {
        BlobContainerClient containerClient = client.getBlobContainerClient("java");
        for (BlobItem blobItem : containerClient.listBlobs()) {
            System.out.println(blobItem.getName());
        }
    }
}

コンテナ内に「aa/サンプル.txt」「aa/ゼリー.txt」「プリン.txt」の3ファイルがある場合以下のように標準出力される。

aa/サンプル.txt
aa/ゼリー.txt
プリン.txt

Blobファイルの取得

OutputStreamで取得する

java」コンテナの「aa/sample.txt」を取得する例を示す。

  1. 取得するBlobファイルが存在するコンテナのBlobContainerClientを取得する。
    BlobContainerClientはコンテナの操作を行うクライアントである。
  2. 取得するBlobファイルのBlobClientを取得する。
    BlobClientはBlobファイルの操作を行うクライアントである。
  3. BlobClientクライアントのdownload(OutputStream)メソッドを呼び出す。
    引数に与えたOutputStreamにBlobファイルの内容が取得される。
import java.io.ByteArrayOutputStream;

import org.springframework.stereotype.Service;

import com.azure.storage.blob.BlobClient;
import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobServiceClientBuilder;

@Service
public class SampleServiceImpl implements SampleService {

    /** BlobServiceClient */
    private BlobServiceClient client;

    /**
     * コンストラクタ
     */
    public SampleServiceImpl(BlobServiceClientBuilder builder) {
        this.client = builder.buildClient();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void doSomething() {
        BlobContainerClient containerClient = client.getBlobContainerClient("java");
        BlobClient blobClient = containerClient.getBlobClient("aa/サンプル.txt");
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        blobClient.download(stream);
    }
}

ファイルで取得する

java」コンテナの「aa/sample.txt」を取得する例を示す。

  1. 取得するBlobファイルが存在するコンテナのBlobContainerClientを取得する。
  2. 取得するBlobファイルのBlobClientを取得する。
  3. BlobClientクライアントのdownloadToFile(String, boolean)メソッドを呼び出す。
    第1引数にはダウンロード先のファイルパス、第2引数にはダウンロード先のファイルパスにファイルが既に存在していた場合に上書きするかどうかを指定する。
    true:ファイルが既に存在していた場合上書きする。 false:ファイルが既に存在していた場合FileAlreadyExistsExceptionがスローされる。
    出力先のフォルダは自動では作成されないのであらかじめ作成しておく。
import java.io.ByteArrayOutputStream;

import org.springframework.stereotype.Service;

import com.azure.storage.blob.BlobClient;
import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobServiceClientBuilder;

@Service
public class SampleServiceImpl implements SampleService {

    /** BlobServiceClient */
    private BlobServiceClient client;

    /**
     * コンストラクタ
     */
    public SampleServiceImpl(BlobServiceClientBuilder builder) {
        this.client = builder.buildClient();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void doSomething() {
        BlobContainerClient containerClient = client.getBlobContainerClient("java");
        BlobClient blobClient = containerClient.getBlobClient("aa/サンプル.txt");
        blobClient.downloadToFile("サンプル.txt", true);
    }
}

InputStreamやbyte[]、Stringで取得

java」コンテナの「aa/sample.txt」を取得する例を示す。

  1. 取得するBlobファイルが存在するコンテナのBlobContainerClientを取得する。
  2. 取得するBlobファイルのBlobClientを取得する。
  3. BlobClientクライアントのdownloadContent()メソッドを呼び出す。 戻り値としてBinaryDataが返される。
    このBinaryDataの持つメソッドでInputStream、byte[]、Stringへと変換可能。
import java.io.InputStream;

import org.springframework.stereotype.Service;

import com.azure.core.util.BinaryData;
import com.azure.storage.blob.BlobClient;
import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobServiceClientBuilder;

@Service
public class SampleServiceImpl implements SampleService {

    /** BlobServiceClient */
    private BlobServiceClient client;

    /**
     * コンストラクタ
     */
    public SampleServiceImpl(BlobServiceClientBuilder builder) {
        this.client = builder.buildClient();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void doSomething() {
        BlobContainerClient containerClient = client.getBlobContainerClient("java");
        BlobClient blobClient = containerClient.getBlobClient("aa/サンプル.txt");
        BinaryData data = blobClient.downloadContent();
        String string = data.toString();
        byte[] bytes = data.toBytes();
        InputStream stream = data.toStream();
    }
}

Blobファイルの登録

BinaryDataをアップロードする

java」コンテナに「プリン.txt」をアップロードする例を示す。

  1. Blobファイルの登録先コンテナのBlobContainerClientを取得する。
  2. 登録するBlobファイルのBlobClientを取得する。
  3. BlobClientクライアントのupload(BinaryData, boolean)メソッドを呼び出す。
    第2引数はファイルが既に存在していた場合に上書きするかどうかを指定する。
    falseを指定した場合、すでにファイルが存在する場合はBlobStorageExceptionがスローされる。
import org.springframework.stereotype.Service;

import com.azure.core.util.BinaryData;
import com.azure.storage.blob.BlobClient;
import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobServiceClientBuilder;

@Service
public class SampleServiceImpl implements SampleService {

    /** BlobServiceClient */
    private BlobServiceClient client;

    /**
     * コンストラクタ
     */
    public SampleServiceImpl(BlobServiceClientBuilder builder) {
        this.client = builder.buildClient();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void doSomething() {
        BlobContainerClient containerClient = client.getBlobContainerClient("java");
        BlobClient blobClient = containerClient.getBlobClient("プリン.txt");
        String dataSample = "ゼリー";
        blobClient.upload(BinaryData.fromString(dataSample), true);
    }
}

BinaryDataは上記の例ではStringから作成したが、この他にもInputStreambyte[]からも作成可能。 以下はBinaryDataの作成例である。

public void doSomething(InputStream stream, byte[] bytearray) {
    BinaryData.fromStream(stram);
    BinaryData.fromBytes(bytearray);
}

InputStreamからアップロードする

java」コンテナに「プリン.txt」をアップロードする例を示す。

  1. Blobファイルの登録先コンテナのBlobContainerClientを取得する。
  2. 登録するBlobファイルのBlobClientを取得する。
  3. BlobClientクライアントのupload(InputStream, long, boolean)メソッドを呼び出す。 第2引数は正確なデータの長さを指定する。
    第3引数はファイルが既に存在していた場合に上書きするかどうかを指定する。 falseを指定した場合、すでにファイルが存在する場合はBlobStorageExceptionがスローされる。

第2引数に指定したデータ長と実際のデータ長が1バイトでもずれていたらUnexpectedLengthExceptionがスローされる

import java.io.ByteArrayInputStream;
import java.io.IOException;

import org.springframework.stereotype.Service;

import com.azure.storage.blob.BlobClient;
import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobServiceClientBuilder;

@Service
public class SampleServiceImpl implements SampleService {

    /** BlobServiceClient */
    private BlobServiceClient client;

    /**
     * コンストラクタ
     */
    public SampleServiceImpl(BlobServiceClientBuilder builder) {
        this.client = builder.buildClient();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void doSomething() {
        BlobContainerClient containerClient = client.getBlobContainerClient("java");
        BlobClient blobClient = containerClient.getBlobClient("プリン.txt");
        String dataSample = "ゼリー";
        try (ByteArrayInputStream dataStream = new ByteArrayInputStream(dataSample.getBytes())) {
            blobClient.upload(dataStream, 9, true);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

ローカルのファイルをアップロードする

java」コンテナに「プリン.txt」をアップロードする例を示す。

  1. Blobファイルの登録先コンテナのBlobContainerClientを取得する。
  2. 登録するBlobファイルのBlobClientを取得する。
  3. BlobClientクライアントの(String, boolean)メソッドを呼び出す。 第2引数はファイルが既に存在していた場合に上書きするかどうかを指定する。
    falseを指定した場合、すでにファイルが存在する場合はBlobStorageExceptionがスローされる。
    存在しないフォルダをアップロード先に指定した場合、フォルダは自動で作成される。
import org.springframework.stereotype.Service;

import com.azure.core.util.BinaryData;
import com.azure.storage.blob.BlobClient;
import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobServiceClientBuilder;

@Service
public class SampleServiceImpl implements SampleService {

    /** BlobServiceClient */
    private BlobServiceClient client;

    /**
     * コンストラクタ
     */
    public SampleServiceImpl(BlobServiceClientBuilder builder) {
        this.client = builder.buildClient();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void doSomething() {
        BlobContainerClient containerClient = client.getBlobContainerClient("java");
        BlobClient blobClient = containerClient.getBlobClient("プリン.txt");
        blobClient.uploadFromFile("モンブラン.txt", true);
    }
}

Blobファイルの削除

java」コンテナの「プリン.txt」を削除する例を示す。

  1. 削除するBlobファイルが存在するコンテナのBlobContainerClientを取得する。
  2. 削除するBlobファイルのBlobClientを取得する。
  3. BlobClientクライアントのdelete()メソッドを呼び出す。
import org.springframework.stereotype.Service;

import com.azure.storage.blob.BlobClient;
import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobServiceClientBuilder;

@Service
public class SampleServiceImpl implements SampleService {

    /** BlobServiceClient */
    private BlobServiceClient client;

    /**
     * コンストラクタ
     */
    public SampleServiceImpl(BlobServiceClientBuilder builder) {
        this.client = builder.buildClient();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void doSomething() {
        BlobContainerClient containerClient = client.getBlobContainerClient("java");
        BlobClient blobClient = containerClient.getBlobClient("プリン.txt");
        if (blobClient.exists()) {
            blobClient.delete();
        }
    }
}

Blobファイルの存在チェック

java」コンテナに「プリン.txt」のみ存在する場合のチェック例を示す。

  1. 存在を確認したいBlobファイルが存在するコンテナのBlobContainerClientを取得する。 BlobContainerClientはコンテナの操作や設定を行うクライアントである。
  2. 存在を確認したいBlobファイルのBlobClientを取得する。 BlobClientはBlobファイルの操作や設定を行うクライアントである。
  3. BlobClientクライアントのexists()メソッドを呼び出す。
import java.io.ByteArrayOutputStream;

import org.springframework.stereotype.Service;

import com.azure.storage.blob.BlobClient;
import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobServiceClientBuilder;

@Service
public class SampleServiceImpl implements SampleService {

    /** BlobServiceClient */
    private BlobServiceClient client;

    /**
     * コンストラクタ
     */
    public SampleServiceImpl(BlobServiceClientBuilder builder) {
        this.client = builder.buildClient();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void doSomething() {
        BlobContainerClient containerClient = client.getBlobContainerClient("java");
        BlobClient blobClient = containerClient.getBlobClient("プリン.txt");
        Boolean exists = blobClient.exists(); // true
        BlobClient blobClient2 = containerClient.getBlobClient("ゼリー.txt");
        Boolean exists2 = blobClient2.exists(); // false
    }
}

BlobファイルをDIする

@Valueでorg.springframework.core.io.ResourceクラスにDIすることができる。

@Valueの属性にazure-blob://コンテナ名/Blob名の形式でファイルを指定する。

import java.io.InputStream;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;

@Service
public class SampleServiceImpl implements SampleService {

    @Value("azure-blob://java/プリン.txt")
    private Resource blobFile;

    /**
     * {@inheritDoc}
     */
    @Override
    public void doSomething() {
        InputStream inputStream = blobFile.getInputStream();
    }
}