How to Simplify Multi‑Platform File Storage in Spring Boot with x‑file‑storage
This tutorial shows how to use the x‑file‑storage library to unify file operations across multiple storage platforms such as Amazon S3, MinIO, and RustFS in a Spring Boot application, providing step‑by‑step Docker setup, Maven configuration, YAML settings, and controller code.
Introduction
Various file storage services (Alibaba OSS, Tencent COS, Amazon S3, MinIO, RustFS, etc.) require different SDKs, making platform switching cumbersome. The x-file-storage library offers a universal solution that enables file storage with a single line of code.
Supported Platforms
The library supports most mainstream storage platforms. Below is an illustration of the supported platforms.
Usage with RustFS (Amazon S3 V2 compatible)
RustFS
Run RustFS in a Docker container:
docker run -p 9000:9000 --name rustfs \
-e RUSTFS_ACCESS_KEY=rustfsadmin \
-e RUSTFS_SECRET_KEY=rustfsadmin \
-v /mydata/rustfs/data:/data \
-v /etc/localtime:/etc/localtime \
-d rustfs/rustfsAfter the container starts, log into the RustFS console and create a bucket named simple (access via http://192.168.3.101:9000).
Integrate the library into a Spring Boot project:
<!-- x-file-storage dependency -->
<dependency>
<groupId>org.dromara.x-file-storage</groupId>
<artifactId>x-file-storage-spring</artifactId>
<version>${x-file-storage.version}</version>
</dependency>
<!-- AWS S3 Java SDK dependency -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
<version>${aws-s3-sdk.version}</version>
</dependency>Add the following configuration to application.yml:
dromara:
x-file-storage:
default-platform: amazon-s3-v2-1
amazon-s3-v2:
# Amazon S3 V2
- platform: amazon-s3-v2-1 # storage platform identifier
enable-storage: true # enable storage
access-key: rustfsadmin
secret-key: rustfsadmin
region: ap-east-1 # required
end-point: http://192.168.3.101:9000 # required
bucket-name: simple
domain: http://192.168.3.101:9000/Enable file storage in the main class:
@EnableFileStorage
@SpringBootApplication
public class SpringFileStorageApplication {
public static void main(String[] args) {
SpringApplication.run(SpringFileStorageApplication.class, args);
}
}Create a controller that injects FileStorageService and provides upload and delete endpoints:
@Controller
@Tag(name = "FileStorageController", description = "x-file-storage file management")
@RequestMapping("/storage")
public class FileStorageController {
@Autowired
private FileStorageService fileStorageService;
@Operation(summary = "File upload")
@RequestMapping(value = "/upload", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ResponseBody
public CommonResult<FileStorageResult> upload(@RequestPart("file") MultipartFile file) {
FileInfo fileInfo = fileStorageService.of(file).upload();
FileStorageResult result = new FileStorageResult();
result.setName(fileInfo.getFilename());
result.setUrl(fileInfo.getUrl());
return CommonResult.success(result);
}
@Operation(summary = "File delete")
@RequestMapping(value = "/delete", method = RequestMethod.POST)
@ResponseBody
public CommonResult delete(@RequestParam("objectName") String objectName) {
FileInfo fileInfo = new FileInfo().setFilename(objectName).setPlatform("amazon-s3-v2-1");
fileStorageService.delete(fileInfo);
return CommonResult.success(null);
}
}Usage with MinIO
Run MinIO in Docker:
docker run -p 9090:9000 -p 9091:9001 --name minio \
-v /mydata/minio/data:/data \
-e MINIO_ROOT_USER=minioadmin \
-e MINIO_ROOT_PASSWORD=minioadmin \
-d minio/minio server /data --console-address ":9091"Create a bucket named simple via the MinIO console (access at http://192.168.3.101:9091).
Add MinIO dependency to pom.xml:
<!-- MinIO dependency -->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>${minio-sdk.version}</version>
</dependency>Configure MinIO in application.yml:
dromara:
x-file-storage:
minio:
- platform: minio-1 # storage platform identifier
enable-storage: true
access-key: minioadmin
secret-key: minioadmin
end-point: http://192.168.3.101:9090
bucket-name: simple
domain: http://192.168.3.101:9090/Update the controller to support MinIO by setting the platform:
@Operation(summary = "File upload")
@RequestMapping(value = "/upload-minio", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ResponseBody
public CommonResult<FileStorageResult> uploadMinIO(@RequestPart("file") MultipartFile file) {
FileInfo fileInfo = fileStorageService.of(file).setPlatform("minio-1").upload();
FileStorageResult result = new FileStorageResult();
result.setName(fileInfo.getFilename());
result.setUrl(fileInfo.getUrl());
return CommonResult.success(result);
}
@Operation(summary = "File delete")
@RequestMapping(value = "/delete-minio", method = RequestMethod.POST)
@ResponseBody
public CommonResult deleteMinio(@RequestParam("objectName") String objectName) {
FileInfo fileInfo = new FileInfo().setFilename(objectName).setPlatform("minio-1");
fileStorageService.delete(fileInfo);
return CommonResult.success(null);
}Testing
Start the Spring Boot application and use the Swagger UI (e.g., http://localhost:8088/swagger-ui/index.html) to test the upload and delete endpoints for both RustFS and MinIO.
Conclusion
The x-file-storage library provides a consistent API for multiple storage back‑ends, allowing developers to switch platforms with minimal code changes. By adding the appropriate SDK dependency and a few configuration lines, file operations become straightforward across Amazon S3, MinIO, RustFS, and other services.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
