Spring Boot 中上传文件到 Minio
一、需求背景
在写苍穹外卖这个项目时需要alioss上传,没有自己的oss,发现了Minio这个项目,本着有点编程经验,折腾一下,也能让自己理解的更加深刻😀
二、项目介绍
1、Minio
开源分布式存储方案(Goland编写), 本文只是单机部署一下,替代oss方案
2、苍穹外卖
无需多言,黑马出品,项目组人数众多😀
三、项目配置
1、除java主程序在windows外, mysql,redis,Minio、等都是在wsl2里通过原生docker启动
tips:随便找个dnpm的 docker-compose改改就行
version: "3"
services:
mysql:
image: mysql:${MYSQL_VERSION}
container_name: mysql
volumes:
- ${MYSQL_DATA}:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
TZ: "$TZ"
ports:
- ${MYSQL_PORT}:3306
redis:
image: redis:${REDIS_VERSION}
container_name: redis
restart: always
volumes:
- ${REDIS_DATA}:/data
- ${REDIS_CONF}:/usr/local/etc/redis/redis.conf
ports:
- ${REDIS_PORT}:6379
command: [ redis-server, "/usr/local/etc/redis/redis.conf" ]
minio:
image: minio/minio
hostname: "minio"
ports:
- 9000:9000 # api 端口
- 9001:9001 # 控制台端口
environment:
MINIO_ACCESS_KEY: admin #管理后台用户名
MINIO_SECRET_KEY: admin123 #管理后台密码,最小8个字符
volumes:
- /docker/minio/data:/data #映射当前目录下的data目录至容器内/data目录
- /docker/minio/config:/root/.minio/ #映射配置目录
command: server --console-address ':9001' /data #指定容器中的目录 /data
privileged: true
restart: always
2、引入maven坐标
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.2.0</version>
</dependency>
3、docker-composer 镜像运行后配置Minio
①进入后台管理界面并登录
②创建桶
③配置桶权限及创建密钥
创建密钥并记录保存密钥
四、代码实现
1、创建Minio配置对象类
package com.sky.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "sky.minio")
@Data
public class MinioProperties {
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;
}
2、配置application-dev.yml
sky:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
host: localhost
port: 3306
database: sky_take_out
username: root
password: root
#增加Minio配置
minio:
# API 端点
endpoint: "http://127.0.0.1:9000/"
# 上传的 Bucket
bucket-name: sky-take-out
# Access Key
access-key-id: *****
# Secret Key
access-key-secret: *****
3、创建Minio工具类
package com.sky.utils;
import io.minio.errors.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
@Data
@AllArgsConstructor
@Slf4j
public class MinioUtil {
private String endpoint;
private String accessKey;
private String secretKey;
private String bucketName;
public String upload(MultipartFile file, String objectName) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
// 实例化客户端
MinioClient client = MinioClient.builder()
.endpoint(this.endpoint)
.credentials(this.accessKey, this.secretKey)
.build();
InputStream inputStream = null;
try {
inputStream = file.getInputStream();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
client.putObject(PutObjectArgs.builder()
.bucket(this.bucketName)
.object(objectName)
.stream(inputStream, file.getSize(), -1)
.contentType(file.getContentType())
.build());
return this.endpoint + this.bucketName + "/" + objectName;
}
}
4、创建公用的控制器并注入MinioUtil实例
package com.sky.controller.admin;
import com.sky.result.Result;
import com.sky.utils.MinioUtil;
import io.minio.errors.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;
/**
* 通用接口
*/
@RequestMapping("/admin/common")
@RestController
@Api(tags = "通用接口")
@Slf4j
public class CommonController {
@Autowired
private MinioUtil minioUtil;
/**
* 文件上传
* @param file
* @return
*/
@ApiOperation("文件上传接口")
@PostMapping("/upload")
public Result<String> upload(MultipartFile file) {
log.info("文件上传 : {}", file);
String originalFilename = file.getOriginalFilename();
String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
String objectName = UUID.randomUUID() + extension;
String filePath = null;
try {
filePath = minioUtil.upload(file, objectName);
return Result.success(filePath);
} catch (Exception e) {
log.error("文件上传失败: {}", e);
return Result.error("文件上传失败");
}
}
}
五、结果展示
本作品采用《CC 协议》,转载必须注明作者和本文链接