minio的使用
场景
当后端项目需要进行文件存储时,一般会借助第三方的文件存储服务,Minio就是一个开源的文件存储服务,它自带前后端。
Minio安装
Minio可以借助docker进行安装,安装难度不高,详细看:Minio安装
SpringBoot继承Minio
Springboot上传文件到Minio容器
创建文件上传接口
// 以MultipartFile接收文件
@RequestMapping(value = "/minio", method = RequestMethod.POST)
public Result<Map<String, String>> minioUpload(@RequestParam("file") MultipartFile file) throws Exception {
String fileUrl = minio.upload(file);
Map<String, String> map = new HashMap<>();
map.put("fileUrl", fileUrl);
return Result.ok(map);
}
准备Minio所需要的参数
可以准备一个properties文件,将其与配置文件进行关联。
@Data
@ConfigurationProperties(prefix = "minio")
public class MinioProperties {
// Minio部署地址,端口默认为9000
private String endPointUrl;
// Minio登录账号
private String accessKey;
// Minio登陆密码
private String secretKey;
// Minio文件存储桶Name
private String bucketName;
}
配置文件如下:
minio:
end-point-url: http://120.46.189.171:9001
access-key: admin
secret-key: admin123456
bucket-name: spzx-bucket
利用配置文件创建对象到IOC容器供后续使用,具体为MinioClient类,需要注入各种参数并且可以判断指定桶是否存在
@Slf4j
public class MinioConfig {
@Autowired
private MinioProperties minioProperties;
@Bean
public MinioClient minioClient() throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
// 创建一个Minio的客户端对象
MinioClient minioClient = MinioClient.builder()
.endpoint(minioProperties.getEndPointUrl())
.credentials(minioProperties.getAccessKey(), minioProperties.getSecretKey())
.build();
// 判断桶是否存在
boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(minioProperties.getBucketName()).build());
if (!found) {
// 如果不存在,那么此时就创建一个新的桶
minioClient.makeBucket(MakeBucketArgs.builder().bucket(minioProperties.getBucketName()).build());
} else {
// 如果存在打印信息
log.info("Bucket 'spzx-bucket' already exists.");
}
return minioClient;
}
}
创建Minio工具类,封装具体的上传细节
@Slf4j
@EnableConfigurationProperties(value = MinioProperties.class)
public class Minio {
@Autowired
private MinioProperties minioProperties;
@Autowired
MinioClient minioClient;
public String upload(MultipartFile multipartFile) throws Exception {
try {
// 设置存储对象名称,通过日期和uuid实现每日数据分开存储
String dateDir = DateUtil.format(new Date(), "yyyyMMdd");
String uuid = UUID.randomUUID().toString().replace("-", "");
//20230801/443e1e772bef482c95be28704bec58a901.jpg
String fileName = dateDir+"/"+uuid+multipartFile.getOriginalFilename();
log.info("upload-filename:{}", fileName);
// 以流的形式上传文件 stream参数为:文件流 文件大小 对象长度(-1表示未知)
PutObjectArgs putObjectArgs = PutObjectArgs.builder()
.bucket(minioProperties.getBucketName())
.stream(multipartFile.getInputStream(), multipartFile.getSize(), -1)
.object(fileName)
.build();
minioClient.putObject(putObjectArgs);
return minioProperties.getEndPointUrl() + "/" + minioProperties.getBucketName() + "/" + fileName ;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
通过一个自定义注解引入Minio服务
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(value = {Minio.class, MinioConfig.class})
public @interface EnableMinio {
}