File Upload, Download, And Delete - Azure Blob Storage + Spring Boot Example
In this section, you will learn how to create a storage account on Microsoft Azure and create a simple spring boot application to perform different file operations such as upload, download, and delete files from the Azure blob storage.
A little bit of Background
Azure Blob Storage
Azure Blob storage is Microsoft's object storage solution for the cloud. Blob storage is optimized for storing massive amounts of unstructured data. Unstructured data is data that doesn't adhere to a particular data model or definition, such as text or binary data.
Spring Boot
Spring Boot makes it easy to create stand-alone, production-grade Spring-based Applications that you can "just run". More Info - https://spring.io/projects/spring-boot
Spring Boot makes it easy to create stand-alone, production-grade Spring-based Applications that you can "just run".
More Info - https://spring.io/projects/spring-boot
Create an Azure Storage Account and blob container using Azure Portal
Sign in to Azure portal https://portal.azure.com/#home and search for "Storage accounts" like below.
Create a storage account,
Enter/Select Resource group, Storage account name, etc... Then click on the "Review + create" button.
Then click on the "Create" button.
Now, You can see "Deployment is in progress" like the below image.
Once deployment is completed you can see the "Your deployment is complete" page like the below image.
Then click on the "Connection String"
Spring boot web application
Final Project Directory:
Pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.1</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.knf.dev.demo</groupId>
<artifactId>spring-azure-storage-blob</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-azure-storage-blob</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-storage-blob</artifactId>
<version>12.13.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.yaml
azure:
storage:
container:
name: <Container name>
connection:
string: <Connection string>
Azure Blob Configuration
package com.knf.dev.demo.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobServiceClientBuilder;
@Configuration
public class AzureBlobConfig {
@Value("${azure.storage.connection.string}")
private String connectionString;
@Value("${azure.storage.container.name}")
private String containerName;
@Bean
public BlobServiceClient clobServiceClient() {
BlobServiceClient blobServiceClient =
new BlobServiceClientBuilder()
.connectionString(connectionString)
.buildClient();
return blobServiceClient;
}
@Bean
public BlobContainerClient blobContainerClient() {
BlobContainerClient blobContainerClient =
clobServiceClient()
.getBlobContainerClient(containerName);
return blobContainerClient;
}
}
Azure Blob Service
package com.knf.dev.demo.service;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import com.azure.core.http.rest.PagedIterable;
import com.azure.storage.blob.BlobClient;
import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.models.BlobItem;
@Component
public class AzureBlobService {
@Autowired
BlobServiceClient blobServiceClient;
@Autowired
BlobContainerClient blobContainerClient;
public String upload(MultipartFile multipartFile)
throws IOException {
// Todo UUID
BlobClient blob = blobContainerClient
.getBlobClient(multipartFile.getOriginalFilename());
blob.upload(multipartFile.getInputStream(),
multipartFile.getSize(), true);
return multipartFile.getOriginalFilename();
}
public byte[] getFile(String fileName)
throws URISyntaxException {
BlobClient blob = blobContainerClient.getBlobClient(fileName);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
blob.download(outputStream);
final byte[] bytes = outputStream.toByteArray();
return bytes;
}
public List<String> listBlobs() {
PagedIterable<BlobItem> items = blobContainerClient.listBlobs();
List<String> names = new ArrayList<String>();
for (BlobItem item : items) {
names.add(item.getName());
}
return names;
}
public Boolean deleteBlob(String blobName) {
BlobClient blob = blobContainerClient.getBlobClient(blobName);
blob.delete();
return true;
}
}
Create a Controller
package com.knf.dev.demo.controller;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.knf.dev.demo.service.AzureBlobService;
@RestController
@RequestMapping("/files")
public class AzureController {
@Autowired
private AzureBlobService azureBlobAdapter;
@PostMapping
public ResponseEntity<String> upload
(@RequestParam MultipartFile file)
throws IOException {
String fileName = azureBlobAdapter.upload(file);
return ResponseEntity.ok(fileName);
}
@GetMapping
public ResponseEntity<List<String>> getAllBlobs() {
List<String> items = azureBlobAdapter.listBlobs();
return ResponseEntity.ok(items);
}
@DeleteMapping
public ResponseEntity<Boolean> delete
(@RequestParam String fileName) {
azureBlobAdapter.deleteBlob(fileName);
return ResponseEntity.ok().build();
}
@GetMapping("/download")
public ResponseEntity<Resource> getFile
(@RequestParam String fileName)
throws URISyntaxException {
ByteArrayResource resource =
new ByteArrayResource(azureBlobAdapter
.getFile(fileName));
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\""
+ fileName + "\"");
return ResponseEntity.ok().contentType(MediaType
.APPLICATION_OCTET_STREAM)
.headers(headers).body(resource);
}
}
Spring Boot Main Driver
package com.knf.dev.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Local Setup and Run the application
Step 1: Download or clone the source code from GitHub to a local machine - Click here
Step 2: mvn clean install
Step 3: Run the Spring Boot application -
mvn spring-boot:run or Run as Spring Boot application.
Download the complete source code - click here
Testing APIs using the Postman
1. Upload a file
2. Delete a file
3. Get all file names
4. Download a file
Go to the container and you can see the uploaded files,