不知道为什么使用minio自带的okhttp总是报错找不到mino。所以我依赖了okhttp,因为我这个minio使用docker部署的版本比较高是社区版,所以我在代码中创建桶设置了访问策略,要不然默认是private。
java项目pom.xml文件添加依赖:
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.11.0</version>
</dependency>
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.5.9</version>
</dependency>
添加config
package com.test.config.minio;
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 MinioConfig {
/**
* 连接地址
*/
private String endpoint;
/**
* 用户名
*/
private String accessKey;
/**
* 密码
*/
private String secretKey;
private String bucketName;
@Bean
public MinioClient minioClient() {
return MinioClient.builder()
.endpoint(endpoint)
.credentials(accessKey, secretKey)
.build();
}
}
application.yml配置
minio:
endpoint: http://127.0.0.1:9000 #MinIO资源地址
accessKey: minioadmin #访问key
secretKey: minioadmin #访问密钥
bucketName: test #存储桶名称
# 对外访问前缀
public-url-prefix: http://127.0.0.1:9000/test
util工具类
package com.test.common.util;
import com.nuctech.ims.config.minio.MinioConfig;
import io.minio.*;
import io.minio.http.Method;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
import static cn.dev33.satoken.SaManager.log;
@Component
public class MinioUtil {
@Autowired
private MinioClient minioClient;
@Autowired
private MinioConfig minioConfig;
/**
* 创建存储bucket
*
* @param bucketName 存储bucket名称
* @return Boolean
*/
public boolean makeBucket(String bucketName) {
try {
// 1. 创建 bucket
boolean exists = minioClient.bucketExists(
BucketExistsArgs.builder().bucket(bucketName).build());
if (!exists) {
minioClient.makeBucket(
MakeBucketArgs.builder().bucket(bucketName).build());
}
// 2. 设置为 public 访问
String policy = buildPublicReadPolicy(bucketName);
minioClient.setBucketPolicy(
SetBucketPolicyArgs.builder()
.bucket(bucketName)
.config(policy)
.build());
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* 删除存储bucket
*
* @param bucketName 存储bucket名称
* @return Boolean
*/
public boolean removeBucket(String bucketName) {
try {
minioClient.removeBucket(RemoveBucketArgs.builder()
.bucket(bucketName)
.build());
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
private String buildPublicReadPolicy(String bucketName) {
return "{\n" +
" \"Version\": \"2012-10-17\",\n" +
" \"Statement\": [\n" +
" {\n" +
" \"Effect\": \"Allow\",\n" +
" \"Principal\": \"*\",\n" +
" \"Action\": [\"s3:GetObject\"],\n" +
" \"Resource\": [\"arn:aws:s3:::" + bucketName + "/*\"]\n" +
" }\n" +
" ]\n" +
"}";
}
/**
* 查看存储bucket是否存在
*
* @param bucketName
* @return
*/
public boolean bucketExists(String bucketName) {
try {
return minioClient.bucketExists(BucketExistsArgs
.builder()
.bucket(bucketName)
.build());
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* 文件上传
*
* @param file 文件
* @return
*/
public String uploadFile(MultipartFile file) {
try {
if (file == null || file.getSize() == 0) {
log.error("上传文件异常:文件大小为空");
throw new RuntimeException("文件大小不能为空");
}
//文件的原始名称
String originalFilename = file.getOriginalFilename();
//文件的ContentType
String contentType = file.getContentType();
// 生成存储对象的名称(将 UUID 字符串中的 - 替换成空字符串)
String key = UUID.randomUUID().toString().replace("-", "");
// 获取文件的后缀,如 .jpg
String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
// 拼接上文件后缀,即为要存储的文件名
//拼写图片路径
//拼写图片路径
String fileName = new SimpleDateFormat("yyyy/MM/dd").format(new Date())
+"/"+ UUID.randomUUID().toString()+originalFilename.substring(originalFilename.lastIndexOf("."));
// String fileName = String.format("%s%s", key, suffix);
// 上传文件至 Minio
minioClient.putObject(PutObjectArgs.builder()
.bucket(minioConfig.getBucketName())
.object(fileName)
.stream(file.getInputStream(), file.getSize(), -1)
.contentType(contentType)
.build());
// 返回文件的访问链接
String url = String.format("%s/%s/%s", minioConfig.getEndpoint(), minioConfig.getBucketName(), fileName);
return url;
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
/**
* 获取对象url
*
* @param objectName 对象名称
* @return
*/
public String getObjectUrl(String objectName) {
try {
return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
.method(Method.GET)
.bucket(minioConfig.getBucketName())
.object(objectName)
.build());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
controller
package com.test.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import com.nuctech.ims.common.model.Result;
import com.nuctech.ims.common.util.MinioUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import static cn.dev33.satoken.SaManager.log;
@SaCheckLogin
@RestController
@RequestMapping("/file")
public class FileController {
@Autowired
private MinioUtil minioUtil;
/**
* 创建存储bucket
*
* @param bucketName
* @return
*/
@PostMapping("makeBucket")
public Result<Void> makeBucket(String bucketName) {
boolean success = minioUtil.makeBucket(bucketName);
return Result.success();
}
/**
* 删除存储bucket
*
* @param bucketName
* @return
*/
@PostMapping("removeBucket")
public Result<Void> removeBucket(String bucketName) {
boolean success = minioUtil.removeBucket(bucketName);
return Result.success();
}
/**
* 查看存储bucket是否存在
*
* @param bucketName
* @return
*/
@GetMapping("bucketExists")
public Result<Void> bucketExists(String bucketName) {
boolean success = minioUtil.bucketExists(bucketName);
return Result.success();
}
/**
* 文件上传
*
* @param file
* @return
*/
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Result<String> uploadFile(@RequestParam("file") MultipartFile file) {
try {
// 上传文件
String url = minioUtil.uploadFile(file);
// 构建成功返参,将图片的访问链接返回
return Result.success(url);
} catch (Exception e) {
// 手动抛出业务异常,提示 "文件上传失败"
log.error("文件上传失败:{}", file);
e.printStackTrace();
return null;
}
}
/**
* 获取对象url
*
* @param objectName
* @return
*/
@GetMapping("getObjectUrl")
public Result<String> getObjectUrl(String objectName) {
String fileUrl = minioUtil.getObjectUrl(objectName);
return Result.success(fileUrl);
}
}