一、什么是minio?
说白了,minio就是一个高性能的对象存储。就像我们用的百度网盘一样,可以用来存各种各样的文件,我们可以将静态资源文件 图片视频啥的存储在minio中,减少服务器的压力。和阿里云的OSS对象存储服务 一样。
minio官网:https://min.io/
二、安装minio (使用docker搭建minio服务)
1、docker 命令
Linux:
docker run -p 9000:9000 -p 9001:9001 --name my-minio-server --privileged=true
-e “MINIO_ROOT_USER=yangzihao”
-e “MINIO_ROOT_PASSWORD=miniopassword”
-v /home/minio/data:/data
-v /home/minio/config:/root/.minio
-d minio/minio server /data --console-address “:9001”
MINIO_ROOT_USER
为自定义的用户名MINIO_ROOT_PASSWORD
为自定义的密码console-address
控制台的地址
2、访问
浏览器输入http://localhost:9000
就可以看到minio的控制台了
输入 刚刚自定义的 用户名和密码 即可访问啦~~~
进入之后可以 点击 create bucket ,创建一个bucket后就可以愉快的upload 文件啦!!!
上传完之后就可以通过http://localhost:9000/bucket名/xx文件名来访问文件了
三、SpringBoot整合minio实现文件上传
创建一个基本的SpringBoot项目,导入如下依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.2.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
输入如下配置
spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 10MB
minio:
access-key: yangzihao #key就是docker初始化是设置的,密钥相同
secret-key: miniopassword # 就是刚刚docker 命令中的密码
url: http://localhost:9000
bucket-name: my-minio-test #就是刚刚创建的bucket
thymeleaf:
cache: false
创建一个Minio配置类,将配置文件中的参数与属性进行绑定,然后创建一个MinioClient注册进容器。
@Data
@Configuration
@ConfigurationProperties(prefix = "spring.minio")
public class MinioConfiguration {
private String accessKey;
private String secretKey;
private String url;
private String bucketName;
@Bean
public MinioClient minioClient(){
return MinioClient.builder()
.endpoint(url)
.credentials(accessKey,secretKey)
.build();
}
}
下面是一个minio client 操作minio的简单方法的组件。
@Component
public class MinioUtils {
@Autowired
private MinioClient minioClient;
@Autowired
private MinioConfiguration configuration;
/**
* 获取上传临时签名
*/
@SneakyThrows
public Map getPolicy(String fileName, ZonedDateTime time) {
PostPolicy postPolicy = new PostPolicy(configuration.getBucketName(), time);
postPolicy.addEqualsCondition("key", fileName);
try {
Map<String, String> map = minioClient.getPresignedPostFormData(postPolicy);
HashMap<String, String> map1 = new HashMap<>();
map.forEach((k,v)->{
map1.put(k.replaceAll("-",""),v);
});
map1.put("host",configuration.getUrl()+"/"+configuration.getBucketName());
return map1;
} catch (ErrorResponseException e) {
e.printStackTrace();
} catch (InsufficientDataException e) {
e.printStackTrace();
} catch (InternalException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidResponseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (ServerException e) {
e.printStackTrace();
} catch (XmlParserException e) {
e.printStackTrace();
}
return null;
}
/**
* 获取上传文件的url
*/
public String getPolicyUrl(String objectName, Method method, int time, TimeUnit timeUnit) {
try {
return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
.method(method)
.bucket(configuration.getBucketName())
.object(objectName)
.expiry(time, timeUnit).build());
} catch (ErrorResponseException e) {
e.printStackTrace();
} catch (InsufficientDataException e) {
e.printStackTrace();
} catch (InternalException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidResponseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (XmlParserException e) {
e.printStackTrace();
} catch (ServerException e) {
e.printStackTrace();
}
return null;
}
/**
* 上传文件
*/
public void upload(MultipartFile file, String fileName) {
// 使用putObject上传一个文件到存储桶中。
try {
InputStream inputStream = file.getInputStream();
minioClient.putObject(PutObjectArgs.builder()
.bucket(configuration.getBucketName())
.object(fileName)
.stream(inputStream, file.getSize(), -1)
.contentType(file.getContentType())
.build());
} catch (ErrorResponseException e) {
e.printStackTrace();
} catch (InsufficientDataException e) {
e.printStackTrace();
} catch (InternalException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidResponseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (ServerException e) {
e.printStackTrace();
} catch (XmlParserException e) {
e.printStackTrace();
}
}
/**
* 根据filename获取文件访问地址
*/
public String getUrl(String objectName, int time, TimeUnit timeUnit) {
String url = null;
try {
url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
.method(Method.GET)
.bucket(configuration.getBucketName())
.object(objectName)
.expiry(time, timeUnit).build());
} catch (ErrorResponseException e) {
e.printStackTrace();
} catch (InsufficientDataException e) {
e.printStackTrace();
} catch (InternalException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidResponseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (XmlParserException e) {
e.printStackTrace();
} catch (ServerException e) {
e.printStackTrace();
}
return url;
}
}
编写上传文件Controller和接口
@RestController
@RequestMapping("/upload")
public class UploadController {
@Autowired
private MinioConfiguration minioConfiguration;
@Autowired
private MinioUtils minioUtils;
@PostMapping("/uploadFileTest")
public String uploadFileTest(MultipartFile file){
String newFileName= UUID.randomUUID().toString();
int lastIndexOf = file.getOriginalFilename().lastIndexOf(".");
String suffixName = file.getOriginalFilename().substring(lastIndexOf);
minioUtils.upload(file,newFileName+suffixName);
return minioConfiguration.getUrl()+"/"+minioConfiguration.getBucketName()+"/"+newFileName+suffixName;
}
}
四、上传测试
使用Postman测试接口
访问接口返回的地址
上传成功!!!完结撒花…
五、后记
生活明朗,万物可爱,人间值得,未来可期。