【minio】第三章--集成springboot
我们在学完minio的基础理论知识后,最重要的就是上手操作,接下来我就简单做个demo,springboot集成minio。
第一步:添加minio相关依赖
<dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-stdlib</artifactId> <version>1.3.70</version></dependency><dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>8.3.4</version> <exclusions> <exclusion> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> </exclusion> <exclusion> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-stdlib</artifactId> </exclusion> </exclusions></dependency>
第二步:添加配置文件
minio: endpoint: http://127.0.0.1:9000/ accessKey: minio secretKey: minio123456
第三步:编写配置类
这一步主要目的是为了从配置文件中引入minio相关值,并编写bean用于初始化minio
@Configuration
public class MinioConfig {
@Value("${minio.endpoint}")
private String endpoint;
@Value("${minio.accessKey}")
private String accessKey;
@Value("${minio.secretKey}")
private String secretKey;
@Bean
public MinioClient createMinioClient() {
System.out.println("endpoint:" + endpoint);
System.out.println("accessKey:" + accessKey);
System.out.println("secretKey:" + secretKey);
MinioClient minioClient = MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey)
.build();
return minioClient;
}
}
第四步:编写工具类
这一步就是用来封装minio提供的sdk,方便我们调用
@Service
public class MinioUtil {
@Autowired
private MinioClient minioClient;
private String bucketName = "gyh";
private int partSize;
//桶相关操作
/**
* 判断桶是否存在
* @param bucketName 桶名
* @return
*/
public boolean bucketExists(String bucketName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, InternalException, XmlParserException, ErrorResponseException, ServerException {
return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
}
/**
* 创建桶
* @param bucketName 桶名
*/
public void createBucket(String bucketName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
}
}
/**
* 获取全部桶信息
* @return
*/
public List<Bucket> getAllBuckets() throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
return minioClient.listBuckets();
}
/**
* 删除桶
* @param bucketName
*/
public void removeBucket(String bucketName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
}
//文件相关操作
/**
* 判断文件是否存在
* @param bucketName 桶名
* @param objectName 文件名(minio全路径)
* @return
*/
public boolean objectExist(String bucketName, String objectName) {
boolean exist = true;
try {
minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build());
} catch (Exception e) {
exist = false;
}
return exist;
}
/**
* 获取文件信息
* @param bucketName
* @param objectName
* @return
*/
public StatObjectResponse getObjectInfo(String bucketName, String objectName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
StatObjectResponse statObjectResponse = minioClient.statObject(StatObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.build());
return statObjectResponse;
}
/**
* 判断文件夹是否存在
* @param bucketName 桶名
* @param objectName 文件名
* @return
*/
public boolean folderExist(String bucketName, String objectName) {
boolean exist = false;
try {
Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder()
.bucket(bucketName)
.prefix(objectName)
.recursive(false)
.build());
for (Result<Item> result : results) {
Item item = result.get();
if (item.isDir() && objectName.equals(item.objectName())) {
exist = true;
}
}
} catch (Exception e) {
exist = false;
}
return exist;
}
/**
* 根据文件前置查询文件
* @param bucketName 桶名
* @param prefix 前缀名
* @param recursive 是否递归查询
* @return
*/
public List<Item> getAllObjectsByPrefix(String bucketName, String prefix, boolean recursive) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
List<Item> list = new ArrayList<Item>();
Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build());
if (results != null) {
for (Result<Item> result : results) {
Item item = result.get();
list.add(item);
}
}
return list;
}
/**
* 获取路径下文件列表
* @param bucketName 桶名
* @param prefix 文件名称
* @param recursive 是否递归
* @return
*/
public Iterable<Result<Item>> listObject(String bucketName, String prefix, boolean recursive) {
return minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build());
}
/**
* todo 通过流下载
* @param objectName 文件名
* @return
*/
public InputStream getObject(String bucketName, String objectName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
return minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build());
}
/**
* todo 断点下载
* @param bucketName 桶名
* @param objectName 文件名
* @param offset 起始字节的位置
* @param length 要读取的长度
* @return
*/
public InputStream getObject(String bucketName, String objectName, long offset, long length) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
return minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).offset(offset).length(length).build());
}
/**
* todo 上传本地文件
* @param bucketName 桶名
* @param objectName 文件名
* @param fileName 本地文件路径
* @return
*/
public ObjectWriteResponse putObject(String bucketName, String objectName, String fileName) throws IOException, ServerException, InsufficientDataException, InternalException, InvalidResponseException, InvalidKeyException, NoSuchAlgorithmException, XmlParserException, ErrorResponseException {
return minioClient.uploadObject(UploadObjectArgs.builder().bucket(bucketName).object(objectName).filename(fileName).build());
}
/**
* todo 通过流上传文件
* @param bucketName 桶名
* @param objectName 文件名
* @param inputStream 流
*/
public ObjectWriteResponse putObject(String bucketName, String objectName, InputStream inputStream) throws IOException, ServerException, InsufficientDataException, InternalException, InvalidResponseException, InvalidKeyException, NoSuchAlgorithmException, XmlParserException, ErrorResponseException {
return minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName)
.stream(inputStream, inputStream.available(), -1)
.build());
}
/**
* todo 上传文件
* @param bucketName
* @param file
* @return
*/
public ObjectWriteResponse upload(String bucketName, MultipartFile file) throws IOException, ServerException, InsufficientDataException, InternalException, InvalidResponseException, InvalidKeyException, NoSuchAlgorithmException, XmlParserException, ErrorResponseException {
String fileName = file.getOriginalFilename();
return minioClient.putObject(PutObjectArgs.builder()
.bucket(bucketName)
.object(fileName)
.stream(file.getInputStream(), file.getInputStream().available(), -1)
.contentType(file.getContentType())
.build());
}
/**
* todo 分片上传
* @param bucketName
* @param objectName
* @param inputStream
* @param size
* @return
*/
public String chunkedUpload(String bucketName, String objectName, InputStream inputStream, Long size) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
ObjectWriteResponse objectWriteResponse = minioClient.putObject(PutObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.stream(inputStream, size, partSize)
.build());
return objectWriteResponse.object();
}
/**
* 拷贝文件
* @param bucketName 桶名
* @param objectName 文件名
* @param srcBucketName 目标桶名
* @param srcObjectName 目标文件名
* @return
*/
public ObjectWriteResponse copyObject(String bucketName, String objectName, String srcBucketName, String srcObjectName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
return minioClient.copyObject(CopyObjectArgs.builder()
.source(CopySource.builder().bucket(bucketName).object(objectName).build())
.bucket(srcBucketName)
.object(srcObjectName)
.build());
}
/**
* 删除文件
* @param bucketName 桶名
* @param objectName 文件名
*/
public void removeObject(String bucketName, String objectName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build());
}
/**
* 合并文件
* @param bucketName 桶名
* @param objectName 文件名
* @param sources 分片文件list
* @return
*/
public ObjectWriteResponse composeObject(String bucketName, String objectName, List<ComposeSource> sources) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
return minioClient.composeObject(ComposeObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.sources(sources)
.build());
}
}
第五步:编写controller
接下里我们就可以写一些接口去测试
@RestController
@RequestMapping("/minio")
public class MinioController {
@Resource
private MinioUtil minioUtil;
private String bucketName = "gyh";
boolean flag = false;
@GetMapping("/bucketExists")
public boolean bucketExists(@RequestParam(value = "bucketName") String bucketName) throws IOException, InvalidResponseException, InvalidKeyException, NoSuchAlgorithmException, ErrorResponseException, XmlParserException, InsufficientDataException, InternalException, ServerException {
System.out.println(bucketName);
return minioUtil.bucketExists(bucketName);
}
//下载到本地目录
@PostMapping("/download")
public void download(@RequestParam(value = "objectName") String objectName) throws IOException, InvalidResponseException, InvalidKeyException, NoSuchAlgorithmException, ServerException, ErrorResponseException, XmlParserException, InsufficientDataException, InternalException {
InputStream object = minioUtil.getObject(bucketName, objectName);
try {
//本地读取,存到本地
File file = new File("D:\\carfile\\gyh.txt");
FileOutputStream outputStream = new FileOutputStream(file);
int bytesRead;
byte[] buffer = new byte[1024];
while ((bytesRead = object.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
object.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@PostMapping("/upload")
public void upload(MultipartFile file) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, ErrorResponseException, XmlParserException, InternalException {
minioUtil.upload(bucketName, file);
}
}
这样我们就简单的封装好了一个minio,整体来说比较简单,改造你们的项目也非常方便。但今天这个只是个demo,minio的强大远不止如此,我们这里只实现了一些简单功能,包括minio自身提供的分片上传,通过外链上传等等,还有很多很强大的功能,包括我们业务方面的上传下载,都可以越研究越复杂,这个我也不断地在拓展,争取把minio封装的越来越好。
关于源码我这里有,暂时还没有上传到git,迫切需要的话私聊我吧。
查看5道真题和解析