【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,迫切需要的话私聊我吧。