MinIO Overview, Installation, and Spring Boot Integration Guide
This article introduces MinIO as a high‑performance, cloud‑native object storage solution, explains its key features and use cases, provides step‑by‑step Docker installation commands, and demonstrates how to integrate MinIO with Spring Boot through Maven dependencies, configuration, utility classes, service, and controller code.
MinIO is an open‑source object storage suite written in Go, licensed under Apache License v2.0, offering high performance, S3 compatibility, cloud‑native deployment, and erasure‑code protection, making it suitable for private clouds or as a gateway to services like Amazon S3 and Azure.
Key Features
High performance: up to 55 Gb/s read and 35 Gb/s write on standard hardware, supporting objects from a few KB to 5 TB.
Scalable: clusters can be federated into a global namespace across data centers.
Cloud‑native: containerized, Kubernetes‑orchestrated, multi‑tenant.
S3 compatible: works with MinIO SDK, MinIO Client, AWS SDK and CLI.
SDK support: Go, Java, Python, etc.
Graphical UI and erasure‑code based data protection.
Docker Installation
Pull the MinIO image and run it with the required ports, access keys, and data directories:
docker pull minio/minio docker run -p 9000:9000 -p 9001:9001 --name minio -d --restart=always -e "MINIO_ACCESS_KEY=admin" -e "MINIO_SECRET_KEY=admin" -v /home/data:/data -v /home/config:/root/.minio minio/minio server --console-address ":9000" --address ":9001" /dataThe -p flag maps the console (9000) and API (9001) ports, while the environment variables set the console login credentials.
Spring Boot Integration
Add the MinIO Maven dependency:
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.2.1</version>
</dependency>Configure MinIO connection properties in application.yml:
minio:
# Access URL
endpoint: http://192.168.47.148
# API port
port: 9001
# Credentials
accessKey: <span style="color:#98c379;">account</span>
secretKey: <span style="color:#98c379;">password</span>
secure: false
bucket-name: test
image-size: 10485760
file-size: 1073741824Create a configuration class to build a MinioClient bean:
import io.minio.MinioClient;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Data
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioProperties {
private String endpoint;
private Integer port;
private String accessKey;
private String secretKey;
private boolean secure;
private String bucketName;
private long imageSize;
private long fileSize;
@Bean
public MinioClient minioClient() {
return MinioClient.builder()
.endpoint(endpoint, port, secure)
.credentials(accessKey, secretKey)
.build();
}
}Utility class MinioUtil provides methods for bucket management, object upload/download, and presigned URL generation (code omitted for brevity).
Service implementation MinioServiceImpl delegates to the utility class and builds public URLs after upload:
import com.java.family.minio.config.MinioProperties;
import com.java.family.minio.service.MinioService;
import com.java.family.minio.utils.MinioUtil;
import io.minio.MinioClient;
import io.minio.messages.Bucket;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;
@Service
public class MinioServiceImpl implements MinioService {
@Autowired
private MinioUtil minioUtil;
@Autowired
private MinioProperties minioProperties;
@Override
public boolean bucketExists(String bucketName) {
return minioUtil.bucketExists(bucketName);
}
@Override
public void makeBucket(String bucketName) {
minioUtil.makeBucket(bucketName);
}
@Override
public List<String> listBucketName() {
return minioUtil.listBucketNames();
}
@Override
public List<Bucket> listBuckets() {
return minioUtil.listBuckets();
}
@Override
public boolean removeBucket(String bucketName) {
return minioUtil.removeBucket(bucketName);
}
@Override
public List<String> listObjectNames(String bucketName) {
return minioUtil.listObjectNames(bucketName);
}
@Override
public String putObject(MultipartFile file, String bucketName, String fileType) {
try {
bucketName = StringUtils.isNotBlank(bucketName) ? bucketName : minioProperties.getBucketName();
if (!this.bucketExists(bucketName)) {
this.makeBucket(bucketName);
}
String fileName = file.getOriginalFilename();
String objectName = UUID.randomUUID().toString().replaceAll("-", "") + fileName.substring(fileName.lastIndexOf('.'));
minioUtil.putObject(bucketName, file, objectName, fileType);
return minioProperties.getEndpoint() + ":" + minioProperties.getPort() + "/" + bucketName + "/" + objectName;
} catch (Exception e) {
e.printStackTrace();
return "上传失败";
}
}
@Override
public InputStream downloadObject(String bucketName, String objectName) {
return minioUtil.getObject(bucketName, objectName);
}
@Override
public boolean removeObject(String bucketName, String objectName) {
return minioUtil.removeObject(bucketName, objectName);
}
@Override
public boolean removeListObject(String bucketName, List<String> objectNameList) {
return minioUtil.removeObject(bucketName, objectNameList);
}
@Override
public String getObjectUrl(String bucketName, String objectName) {
return minioUtil.getObjectUrl(bucketName, objectName);
}
}Controller MinioController exposes REST endpoints for uploading files, creating buckets, listing objects, generating download URLs, and deleting resources:
import com.java.family.minio.service.MinioService;
import com.java.family.minio.utils.FileTypeUtils;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RequestMapping("/minio")
@RestController
public class MinioController {
@Autowired
private MinioService minioService;
@PostMapping("/upload")
public String uploadFile(MultipartFile file, String bucketName) {
String fileType = FileTypeUtils.getFileType(file);
if (fileType != null) {
return minioService.putObject(file, bucketName, fileType);
}
return "不支持的文件格式。请确认格式,重新上传!!!";
}
@PostMapping("/addBucket/{bucketName}")
public String addBucket(@PathVariable String bucketName) {
minioService.makeBucket(bucketName);
return "创建成功!!!";
}
@GetMapping("/show/{bucketName}")
public List<String> show(@PathVariable String bucketName) {
return minioService.listObjectNames(bucketName);
}
@GetMapping("/showBucketName")
public List<String> showBucketName() {
return minioService.listBucketName();
}
@GetMapping("/showListObjectNameAndDownloadUrl/{bucketName}")
public Map<String, String> showListObjectNameAndDownloadUrl(@PathVariable String bucketName) {
Map<String, String> map = new HashMap<>();
List<String> listObjectNames = minioService.listObjectNames(bucketName);
String url = "localhost:8085/minio/download/" + bucketName + "/";
for (String name : listObjectNames) {
map.put(name, url + name);
}
return map;
}
@DeleteMapping("/removeBucket/{bucketName}")
public String delBucketName(@PathVariable String bucketName) {
return minioService.removeBucket(bucketName) ? "删除成功" : "删除失败";
}
@DeleteMapping("/removeObject/{bucketName}/{objectName}")
public String delObject(@PathVariable("bucketName") String bucketName, @PathVariable("objectName") String objectName) {
return minioService.removeObject(bucketName, objectName) ? "删除成功" : "删除失败";
}
@DeleteMapping("/removeListObject/{bucketName}")
public String delListObject(@PathVariable("bucketName") String bucketName, @RequestBody List<String> objectNameList) {
return minioService.removeListObject(bucketName, objectNameList) ? "删除成功" : "删除失败";
}
@RequestMapping("/download/{bucketName}/{objectName}")
public void download(HttpServletResponse response, @PathVariable("bucketName") String bucketName, @PathVariable("objectName") String objectName) {
InputStream in = null;
try {
in = minioService.downloadObject(bucketName, objectName);
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(objectName, "UTF-8"));
response.setCharacterEncoding("UTF-8");
IOUtils.copy(in, response.getOutputStream());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (in != null) {
try { in.close(); } catch (IOException e) { e.printStackTrace(); }
}
}
}
}After deploying the application, you can upload files via the /minio/upload endpoint, view them in the MinIO UI, generate temporary share links (default 7‑day validity), and manage buckets and objects through the provided REST API.
Conclusion
MinIO is a lightweight yet powerful open‑source object storage solution that can be quickly set up with Docker and seamlessly integrated into Java Spring Boot projects, making it an excellent choice for small‑to‑medium backend services or as a free image hosting service.
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.
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
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.
