1. MinIO 简介
MinIO 是一个高性能的开源对象存储服务,兼容 Amazon S3 API,适用于存储非结构化数据(如图片、视频、日志、静态文件等)。它具备高可用性、分布式部署能力,适合作为云原生应用的存储基础设施。
2. Spring Boot 集成 MinIO
2.1 添加依赖
在 pom.xml
中添加以下依赖:
<!-- MinIO Java SDK -->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.5.7</version>
</dependency>
<!-- Spring Boot Web(用于文件操作) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Freemarker 模板引擎 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
2.2 配置 MinIO 参数
在 application.yml
中添加配置:
minio:
endpoint: http://localhost:9000 # MinIO 服务器地址
access-key: your-access-key # 用户名
secret-key: your-secret-key # 密码
bucket: static-files # 默认存储桶名称
secure: false # 是否启用 HTTPS
freemarker:
cache: false # 开发时关闭缓存
charset: UTF-8
check-template-location: true
content-type: text/html
suffix: .ftl
template-loader-path: classpath:/templates/ # Freemarker 模板路径
3. 编写 MinIO 工具类
创建一个 MinioUtils
类,封装文件上传和访问方法:
@Component
public class MinioUtils {
@Value("${minio.endpoint}")
private String endpoint;
@Value("${minio.access-key}")
private String accessKey;
@Value("${minio.secret-key}")
private String secretKey;
@Value("${minio.bucket}")
private String bucketName;
private MinioClient minioClient;
@PostConstruct
public void init() throws Exception {
minioClient = MinioClient.builder()
.endpoint(endpoint)
.credentials(accessKey, secretKey)
.build();
// 检查存储桶是否存在,不存在则创建
if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
}
}
/**
* 上传文件到 MinIO
* @param file 文件对象
* @param filename 存储的文件名(包含路径,如 "css/style.css")
*/
public String uploadFile(MultipartFile file, String filename) throws Exception {
InputStream inputStream = file.getInputStream();
minioClient.putObject(
PutObjectArgs.builder()
.bucket(bucketName)
.object(filename)
.stream(inputStream, file.getSize(), -1)
.contentType(file.getContentType())
.build());
return endpoint + "/" + bucketName + "/" + filename;
}
/**
* 获取文件访问地址
*/
public String getFileUrl(String filename) {
return endpoint + "/" + bucketName + "/" + filename;
}
}
4. 使用工具类上传静态文件
在 Controller 或 Service 中注入 MinioUtils
并上传文件:
@RestController
public class FileController {
@Autowired
private MinioUtils minioUtils;
@PostMapping("/upload")
public String upload(@RequestParam("file") MultipartFile file) {
String filename = "css/" + file.getOriginalFilename(); // 按路径存储
String url = minioUtils.uploadFile(file, filename);
return "文件访问地址: " + url;
}
}
5. 前端访问静态文件
5.1 设置 MinIO 存储桶策略
确保存储桶为公开可读:
- 登录 MinIO 控制台(默认端口 9000)。
- 进入
static-files
存储桶,选择 Manage -> Access Rules。 - 添加规则:前缀
*
,权限readonly
。
5.2 在 Freemarker 模板中引用静态文件
在 .ftl
模板中直接使用 MinIO 的文件 URL:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="${minioUtils.getFileUrl('css/style.css')}">
</head>
<body>
<img src="${minioUtils.getFileUrl('images/logo.png')}">
</body>
</html>
6. 高级配置(可选)
6.1 通过 Nginx 代理 MinIO
隐藏 MinIO 地址,提升安全性:
server {
listen 80;
server_name static.yourdomain.com;
location /static/ {
proxy_pass http://minio-server:9000/static-files/;
}
}
前端访问 URL 变为:http://static.yourdomain.com/static/css/style.css
。
6.2 处理 CORS
在 MinIO 控制台设置 CORS 规则,允许前端域名跨域访问。
总结
通过以上步骤,你的 Spring Boot 项目可以实现:
- 使用 MinIO 存储静态文件(CSS、JS、图片等)。
- 通过工具类便捷管理文件上传。
- 在 Freemarker 模板中直接引用 MinIO 文件地址。
- 前端通过公开 URL 或代理访问静态资源。