目录
1. Minio
1.1 Minio下载
2. Springboot和Minio实现文件存储
Minio是一个灵活、高性能、开源的对象存储解决方案,适用于各种存储需求,并可以与云计算、容器化、大数据和应用程序集成。它为用户提供了自主控制和可扩展性,使其成为一个强大的存储解决方案。
安装 MinIO 服务器,从以下 URL 下载 MinIO 可执行文件:
https://dl.min.io/server/minio/release/windows-amd64/minio.exe
使用此命令启动下载文件夹中的本地 MinIO 实例。
.\minio.exe server C:\minio --console-address :9090
将其输出输出到系统控制台,类似于以下内容:
API: http://192.0.2.10:9000 http://127.0.0.1:9000
RootUser: minioadmin
RootPass: minioadmin
Console: http://192.0.2.10:9090 http://127.0.0.1:9090
RootUser: minioadmin
RootPass: minioadmin
Command-line: https://min.io/docs/minio/linux/reference/minio-mc.html
$ mc alias set myminio http://192.0.2.10:9000 minioadmin minioadmin
Documentation: https://min.io/docs/minio/linux/index.html
WARNING: Detected default credentials 'minioadmin:minioadmin', we recommend that you change these values with 'MINIO_ROOT_USER' and 'MINIO_ROOT_PASSWORD' environment variables.
该过程绑定到当前的 PowerShell 或命令提示符窗口。 关闭窗口将停止服务器并结束进程。
在pom.xml
文件中,添加MinIO的依赖项:
io.minio
minio
8.2.2
在application.properties
文件中,配置MinIO的连接信息:
minio:
endpoint: http://127.0.0.1:9000
accessKey: admin1234
secretKey: admin1234
bucketName: bucket1
在Spring Boot的配置类中,创建MinIO的客户端实例:
@Data
@Configuration
public class MinioConfig {
/**
* 访问地址
*/
@Value("${minio.endpoint}")
private String endpoint;
/**
* accessKey类似于用户ID,用于唯一标识你的账户
*/
@Value("${minio.accessKey}")
private String accessKey;
/**
* secretKey是你账户的密码
*/
@Value("${minio.secretKey}")
private String secretKey;
/**
* 默认存储桶
*/
@Value("${minio.bucketName}")
private String bucketName;
@Bean
public MinioClient minioClient() {
MinioClient minioClient = MinioClient.builder()
.endpoint(endpoint)
.credentials(accessKey, secretKey)
.build();
return minioClient;
}
}
上传和下载文件:
@Slf4j
@RestController
@RequestMapping("/oss")
public class OSSController {
@Autowired
private MinioConfig minioProperties;
@Autowired
private MinioClient minioClient;
/**
* 文件上传
*
* @param file
*/
@PostMapping("/upload")
public String upload(@RequestParam("file") MultipartFile file) throws IOException, ServerException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
if (file == null || file.getSize() == 0) {
log.error("==> 上传文件异常:文件大小为空 ...");
throw new RuntimeException("文件大小不能为空");
}
boolean b = minioClient.bucketExists(BucketExistsArgs.builder().bucket(minioProperties.getBucketName()).build());
if(!b){
minioClient.makeBucket(MakeBucketArgs.builder().bucket(minioProperties.getBucketName()).build());
}
String originalFileName = file.getOriginalFilename();
String contentType = file.getContentType();
String key = UUID.randomUUID().toString().replace("-", "");
String suffix = originalFileName.substring(originalFileName.lastIndexOf("."));
String objectName = String.format("%s%s", key, suffix);
log.info("==> 开始上传文件至 Minio, ObjectName: {}", objectName);
InputStream inputStream = file.getInputStream();
minioClient.putObject(PutObjectArgs.builder()
.bucket(minioProperties.getBucketName())
.object(objectName)
.stream(inputStream, file.getSize(), -1)
.contentType(contentType)
.build());
String url = String.format("%s/%s/%s", minioProperties.getEndpoint(), minioProperties.getBucketName(), objectName);
log.info("==> 上传文件至 Minio 成功,访问路径: {}", url);
inputStream.close();
return url;
}
@GetMapping("/download")
public void download(@RequestParam("filename") String filename, HttpServletResponse response) {
try(InputStream inputStream = minioClient.getObject(GetObjectArgs.builder()
.bucket(minioProperties.getBucketName())
.object(filename)
.build())) {
ServletOutputStream outputStream = response.getOutputStream();
response.setContentType("application/octet-stream");
response.setCharacterEncoding("utf-8");
response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
byte[] bytes = new byte[1024];
int len;
while ((len = inputStream.read(bytes)) > 0) {
outputStream.write(bytes, 0, len);
}
outputStream.close();
} catch (Exception e) {
log.error("file download from minio exception, file name: {}", filename, e);
}
}
}
注意:桶权限设置Access Policy为public,否则无法访问图片