1、minio部署
1.1 拉取镜像
docker pull minio/minio
1.2 创建数据目录
mkdir -p /home/guanz/minio
mkdir -p /home/guanz/minio/midata
1.3 启动minio
docker run -d -p 9000:9000 -p 9001:9001 --restart=always -e MINIO_ACCESS_KEY=guanz -e MINIO_SECRET_KEY=guanz@123 -v $PWD/midata:/data minio/minio server /data --console-address "192.168.1.139:9001"
2、项目搭建
2.1 引入jar
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.0.3</version>
</dependency>
2.2 application-dev.yml
spring
minio:
# Minio服务器地址
endpoint: http://192.168.1.139:9000
port: 9001
create-bucket: true
bucketName: push-test
# Minio服务器账号
accessKey: guanz
# Minio服务器密码
secretKey: guanz@123
secure: false
configDir: /home/push
# 文件大小 单位M
maxFileSize: 10
expires: 604800
2.4 MinioConfig.java
package com.pavis.app.saasbacken.config;
import io.minio.MinioClient;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
/**
* @program: push-saas
* @description:
* @author: Guanzi
* @created: 2021/11/02 13:47
*/
@Data
@Component
@ConfigurationProperties(prefix = "minio")
@Slf4j
@Configuration
public class MinioConfig {
@ApiModelProperty("endPoint是一个URL,域名,IPv4或者IPv6地址")
@Value("${spring.minio.endpoint}")
private String endpoint;
@ApiModelProperty("TCP/IP端口号")
@Value("${spring.minio.port}")
private int port;
@ApiModelProperty("accessKey类似于用户ID,用于唯一标识你的账户")
@Value("${spring.minio.accessKey}")
private String accessKey;
@ApiModelProperty("secretKey是你账户的密码")
@Value("${spring.minio.secretKey}")
private String secretKey;
@ApiModelProperty("如果是true,则用的是https而不是http,默认值是true")
@Value("${spring.minio.secure}")
private Boolean secure;
@ApiModelProperty("默认存储桶")
@Value("${spring.minio.bucketName}")
private String bucketName;
@ApiModelProperty("配置目录")
@Value("${spring.minio.configDir}")
private String configDir;
@ApiModelProperty("文件大小")
@Value("${spring.minio.maxFileSize}")
private Integer maxFileSize;
@ApiModelProperty("签名有效时间")
@Value("${spring.minio.expires}")
private Integer expires;
/**
* 注入minio 客户端
* @return
*/
@Bean
public MinioClient minioClient(){
log.info("endpoint:{},port:{},accessKey:{},secretKey:{},secure:{}",endpoint, port, accessKey, secretKey,secure);
return MinioClient.builder()
.endpoint(endpoint)
.credentials(accessKey, secretKey)
.build();
}
}
3、文件上传
3.1 关键代码
MinioController.java
/**
* 文件上传
* @param file
* @return
*/
@PostMapping("/upload")
public Map<String, Object> upload(MultipartFile file){
return minioService.upload(file);
}
MinioServiceImpl.java
@Override
public Map<String, Object> upload(MultipartFile file) {
Map<String, Object> res = new HashMap<>();
try {
BucketExistsArgs bucketArgs = BucketExistsArgs.builder().bucket(bucketName).build();
// todo 检查bucket是否存在。
boolean found = minioClient.bucketExists(bucketArgs);
PutObjectArgs objectArgs = PutObjectArgs.builder().object(file.getOriginalFilename())
.bucket(bucketName)
.contentType(file.getContentType())
.stream(file.getInputStream(), file.getSize(), -1).build();
ObjectWriteResponse objectWriteResponse = minioClient.putObject(objectArgs);
System.out.println(objectWriteResponse.etag());
res.put("code", "1");
res.put("mess", "ok");
return res;
} catch (Exception e) {
e.printStackTrace();
log.info(e.getMessage());
}
res.put("code", "0");
return res;
}
4、文件下载
@Override
public void download(String filename, HttpServletResponse res) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
BucketExistsArgs bucketArgs = BucketExistsArgs.builder().bucket(bucketName).build();
boolean bucketExists = minioClient.bucketExists(bucketArgs);
log.info("bucketExists:{}", bucketExists);
GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(bucketName)
.object(filename).build();
System.err.println("objectArgs:" + JSON.toJSONString(objectArgs));
try (GetObjectResponse response = minioClient.getObject(objectArgs)) {
System.err.println("response:" + JSON.toJSONString(response));
byte[] buf = new byte[1024];
int len;
try (FastByteArrayOutputStream os = new FastByteArrayOutputStream()) {
while ((len = response.read(buf)) != -1) {
os.write(buf, 0, len);
}
os.flush();
byte[] bytes = os.toByteArray();
res.setCharacterEncoding("utf-8");
res.setContentType("application/force-download");// 设置强制下载不打开
res.addHeader("Content-Disposition", "attachment;fileName=" + filename);
try (ServletOutputStream stream = res.getOutputStream()) {
stream.write(bytes);
stream.flush();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
下载地址:
5、文件永久链接下载
5.1 配置
5.2 关键代码
/**
* 生成一个GET请求的分享链接。
* 失效时间默认是7天。
*
* @param bucketName 存储桶名称
* @param objectName 存储桶里的对象名称
* @param expires 失效时间(以秒为单位),默认是7天,不得大于七天
* @return
*/
public String presignedGetObject(String bucketName, String objectName, Integer expires) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
BucketExistsArgs bucketArgs = BucketExistsArgs.builder().bucket(bucketName).build();
boolean bucketExists = minioClient.bucketExists(bucketArgs);
// boolean flag = bucketExists(bucketName);
String url = "";
if (bucketExists) {
try {
if (expires == null){
expires = 604800;
}
GetPresignedObjectUrlArgs getPresignedObjectUrlArgs = GetPresignedObjectUrlArgs.builder()
.method(Method.GET)
.bucket(bucketName)
.object(objectName)
// .expiry(expires)
.build();
url = minioClient.getPresignedObjectUrl(getPresignedObjectUrlArgs);
log.info("*******url2:{}",url);
} catch (Exception e) {
log.info("presigned get object fail:{}",e);
}
}
return url;
}
下载地址:
http://192.168.1.139:9000/push-test/qiyeku.jpg
至此,springboot+minio 结束。