springboot?Minio功能實(shí)現(xiàn)代碼
1.導(dǎo)入Minio相關(guān)依賴
<dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>8.4.4</version> <exclusions> <exclusion> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>4.10.0</version> </dependency>
2.application.yml 配置信息
spring: # 文件上傳 servlet: multipart: # 單個(gè)文件大小 max-file-size: 500MB # 設(shè)置總上傳的文件大小 max-request-size: 1000MB # MinIO配置 minio: # 服務(wù)地址 endpoint: http://localhost:9000 # 文件地址 fileHost: http://localhost:9000 # 存儲(chǔ)桶名稱 bucket: files # 用戶名 access-key: minioadmin # 密碼 secret-key: minioadmin
3.MinIO配置類
import io.minio.MinioClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * MinIO配置類 * * @date 2023/6/28 */ @Configuration public class MinioConfig { private MinioProperties minioProperties; @Autowired public void setMinioProperties(MinioProperties minioProperties) { this.minioProperties = minioProperties; } /** * 初始化客戶端 * @return 客戶端 */ @Bean public MinioClient minioClient() { return MinioClient.builder() .endpoint(minioProperties.getEndpoint()) .credentials(minioProperties.getAccessKey(), minioProperties.getSecretKey()) .build(); } }
4.Minio實(shí)體類
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; /** * @date 2023/6/28 */ @Configuration @ConfigurationProperties("minio") public class Minio { /** * 服務(wù)地址 */ private String endpoint; /** * 文件預(yù)覽地址 */ private String preview; /** * 存儲(chǔ)桶名稱 */ private String bucket; /** * 用戶名 */ private String accessKey; /** * 密碼 */ private String secretKey; public String getEndpoint() { return endpoint; } public void setEndpoint(String endpoint) { this.endpoint = endpoint; } public String getPreview() { return preview; } public void setPreview(String preview) { this.preview = preview; } public String getBucket() { return bucket; } public void setBucket(String bucket) { this.bucket = bucket; } public String getAccessKey() { return accessKey; } public void setAccessKey(String accessKey) { this.accessKey = accessKey; } public String getSecretKey() { return secretKey; } public void setSecretKey(String secretKey) { this.secretKey = secretKey; } }
5.Minio工具類
import io.minio.*; import io.minio.http.Method; import io.minio.messages.Bucket; import io.minio.messages.Item; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.http.MediaTypeFactory; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.ArrayList; import java.util.List; import java.util.Optional; /** * MinIO實(shí)現(xiàn)類 * * @date 2023/6/28 */ @Slf4j @Component public class MinioUtil { private static MinioClient minioClient; /** * setter注入 * * @param minioClient 客戶端 */ @Autowired public void setMinioClient(MinioClient minioClient) { MinioUtil.minioClient = minioClient; } /** * 啟動(dòng)SpringBoot容器的時(shí)候初始化Bucket,如果沒(méi)有Bucket則創(chuàng)建 */ public static void createBucket(String bucketName) throws Exception { if (!bucketExists(bucketName)) { minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build()); } } /** * 判斷Bucket是否存在 * * @return true:存在,false:不存在 */ public static boolean bucketExists(String bucketName) throws Exception { return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build()); } /** * 獲得Bucket策略 * * @param bucketName 存儲(chǔ)桶名稱 * @return Bucket策略 */ public static String getBucketPolicy(String bucketName) throws Exception { return minioClient.getBucketPolicy(GetBucketPolicyArgs.builder().bucket(bucketName).build()); } /** * 獲得所有Bucket列表 * * @return Bucket列表 */ public static List<Bucket> getAllBuckets(MinioClient minioClient) throws Exception { return minioClient.listBuckets(); } /** * 根據(jù)存儲(chǔ)桶名稱獲取其相關(guān)信息 * * @param bucketName 存儲(chǔ)桶名稱 * @return 相關(guān)信息 */ public static Optional<Bucket> getBucket(String bucketName) throws Exception { return getAllBuckets(minioClient) .stream() .filter(b -> b.name().equals(bucketName)) .findFirst(); } /** * 根據(jù)存儲(chǔ)桶名稱刪除Bucket,true:刪除成功;false:刪除失敗,文件或已不存在 * * @param bucketName 存儲(chǔ)桶名稱 */ public static void removeBucket(String bucketName) throws Exception { minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build()); } /** * 判斷文件是否存在 * * @param bucketName 存儲(chǔ)桶名稱 * @param objectName 文件名 * @return true:存在;false:不存在 */ public static boolean isObjectExist(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 存儲(chǔ)桶名稱 * @param objectName 文件夾名稱 * @return true:存在;false:不存在 */ public static boolean isFolderExist(String bucketName, String objectName) { boolean exist = false; try { ListObjectsArgs listObjectsArgs = ListObjectsArgs.builder() .bucket(bucketName) .prefix(objectName) .recursive(false) .build(); Iterable<Result<Item>> results = minioClient.listObjects(listObjectsArgs); 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; } /** * 根據(jù)文件前綴查詢文件 * * @param bucketName 存儲(chǔ)桶名稱 * @param prefix 前綴 * @param recursive 是否使用遞歸查詢 * @return MinioItem列表 */ public static List<Item> getAllObjectsByPrefix(String bucketName, String prefix, boolean recursive) throws Exception { List<Item> list = new ArrayList<>(); ListObjectsArgs listObjectsArgs = ListObjectsArgs.builder() .bucket(bucketName) .prefix(prefix) .recursive(recursive) .build(); Iterable<Result<Item>> objectsIterator = minioClient.listObjects(listObjectsArgs); if (objectsIterator != null) { for (Result<Item> o : objectsIterator) { Item item = o.get(); list.add(item); } } return list; } /** * 獲取文件流 * * @param bucketName 存儲(chǔ)桶名稱 * @param objectName 文件名 * @return 二進(jìn)制流 */ public static InputStream getObject(String bucketName, String objectName) throws Exception { GetObjectArgs getObjectArgs = GetObjectArgs.builder() .bucket(bucketName) .object(objectName) .build(); return minioClient.getObject(getObjectArgs); } /** * 斷點(diǎn)下載 * * @param bucketName 存儲(chǔ)桶名稱 * @param objectName 文件名稱 * @param offset 起始字節(jié)的位置 * @param length 要讀取的長(zhǎng)度 * @return 二進(jìn)制流 */ public InputStream getObject(String bucketName, String objectName, long offset, long length) throws Exception { GetObjectArgs getObjectArgs = GetObjectArgs.builder() .bucket(bucketName) .object(objectName) .offset(offset) .length(length) .build(); return minioClient.getObject(getObjectArgs); } /** * 獲取路徑下文件列表 * * @param bucketName 存儲(chǔ)桶名稱 * @param prefix 文件名稱 * @param recursive 是否遞歸查找,false:模擬文件夾結(jié)構(gòu)查找 * @return 二進(jìn)制流 */ public static Iterable<Result<Item>> listObjects(String bucketName, String prefix, boolean recursive) { ListObjectsArgs listObjectsArgs = ListObjectsArgs.builder() .bucket(bucketName) .prefix(prefix) .recursive(recursive) .build(); return minioClient.listObjects(listObjectsArgs); } /** * 使用MultipartFile進(jìn)行文件上傳 * * @param bucketName 存儲(chǔ)桶名稱 * @param file 文件名 * @param objectName 對(duì)象名 * @return ObjectWriteResponse對(duì)象 */ public static ObjectWriteResponse uploadFile(String bucketName, MultipartFile file, String objectName) throws Exception { InputStream inputStream = file.getInputStream(); Optional<MediaType> optional = MediaTypeFactory.getMediaType(objectName); String mediaType = optional.orElseThrow(() -> new RuntimeException("文件類型暫不支持")).toString(); PutObjectArgs putObjectArgs = PutObjectArgs.builder() .bucket(bucketName) .object(objectName) .contentType(mediaType) .stream(inputStream, inputStream.available(), -1) .build(); return minioClient.putObject(putObjectArgs); } /** * 上傳本地文件 * * @param bucketName 存儲(chǔ)桶名稱 * @param objectName 對(duì)象名稱 * @param fileName 本地文件路徑 */ public static ObjectWriteResponse uploadFile(String bucketName, String objectName, String fileName) throws Exception { UploadObjectArgs uploadObjectArgs = UploadObjectArgs.builder() .bucket(bucketName) .object(objectName) .filename(fileName) .build(); return minioClient.uploadObject(uploadObjectArgs); } /** * 通過(guò)流上傳文件 * * @param bucketName 存儲(chǔ)桶名稱 * @param objectName 文件對(duì)象 * @param inputStream 文件流 */ public static ObjectWriteResponse uploadFile(String bucketName, String objectName, InputStream inputStream) throws Exception { PutObjectArgs putObjectArgs = PutObjectArgs.builder() .bucket(bucketName) .object(objectName) .stream(inputStream, inputStream.available(), -1) .build(); return minioClient.putObject(putObjectArgs); } /** * 創(chuàng)建文件夾或目錄 * * @param bucketName 存儲(chǔ)桶名稱 * @param objectName 目錄路徑 */ public static ObjectWriteResponse createDir(String bucketName, String objectName) throws Exception { PutObjectArgs putObjectArgs = PutObjectArgs.builder() .bucket(bucketName) .object(objectName) .stream(new ByteArrayInputStream(new byte[]{}), 0, -1) .build(); return minioClient.putObject(putObjectArgs); } /** * 獲取文件信息, 如果拋出異常則說(shuō)明文件不存在 * * @param bucketName 存儲(chǔ)桶名稱 * @param objectName 文件名稱 */ public static String getFileStatusInfo(String bucketName, String objectName) throws Exception { StatObjectArgs statObjectArgs = StatObjectArgs.builder() .bucket(bucketName) .object(objectName) .build(); return minioClient.statObject(statObjectArgs).toString(); } /** * 拷貝文件 * * @param bucketName 存儲(chǔ)桶名稱 * @param objectName 文件名 * @param srcBucketName 目標(biāo)存儲(chǔ)桶 * @param srcObjectName 目標(biāo)文件名 */ public static ObjectWriteResponse copyFile(String bucketName, String objectName, String srcBucketName, String srcObjectName) throws Exception { return minioClient.copyObject(CopyObjectArgs.builder() .source(CopySource.builder() .bucket(bucketName) .object(objectName).build()) .bucket(srcBucketName) .object(srcObjectName).build()); } /** * 刪除文件 * * @param bucketName 存儲(chǔ)桶名稱 * @param objectName 文件名稱 */ public static void removeFile(String bucketName, String objectName) throws Exception { RemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder() .bucket(bucketName) .object(objectName) .build(); minioClient.removeObject(removeObjectArgs); } /** * 批量刪除文件 * * @param bucketName 存儲(chǔ)桶名稱 * @param keys 需要?jiǎng)h除的文件列表 */ public static void removeFiles(String bucketName, List<String> keys) { keys.forEach(key -> { try { removeFile(bucketName, key); } catch (Exception e) { log.error("批量刪除失??!error:{0}", e); } }); } /** * 獲取文件外鏈 * * @param bucketName 存儲(chǔ)桶名稱 * @param objectName 文件名 * @param expires 過(guò)期時(shí)間 <=7 秒 (外鏈有效時(shí)間(單位:秒)) * @return 文件外鏈 */ public static String getPreSignedObjectUrl(String bucketName, String objectName, Integer expires) throws Exception { GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder() .expiry(expires) .bucket(bucketName) .object(objectName) .build(); return minioClient.getPresignedObjectUrl(args); } /** * 獲得文件外鏈 * * @param bucketName 存儲(chǔ)桶名稱 * @param objectName 文件名 * @return 文件外鏈 */ public static String getPreSignedObjectUrl(String bucketName, String objectName) throws Exception { GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder() .bucket(bucketName) .object(objectName) .method(Method.GET) .build(); return minioClient.getPresignedObjectUrl(args); } /** * 將URLDecoder編碼轉(zhuǎn)成UTF8 * * @param str 字符串 * @return 編碼 */ public static String getUtf8ByDecoder(String str) throws UnsupportedEncodingException { String url = str.replaceAll("%(?![0-9a-fA-F]{2})", "%25"); return URLDecoder.decode(url, "UTF-8"); } }
6.Minio控制類
import org.apache.tomcat.util.http.fileupload.IOUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.Arrays; @RestController @RequestMapping("/minio") @CrossOrigin public class MinioController { @Autowired private Minio minio; @Autowired private MinioUtil minioService; /** * 上傳文件 */ @PostMapping(value = "/upload") public String upload(@RequestParam(name = "file") MultipartFile multipartFile) throws Exception { String fileName = multipartFile.getOriginalFilename(); minioService.createBucket(minio.getBucket()); minioService.uploadFile(minio.getBucket(), multipartFile, fileName); return minioService.getPreSignedObjectUrl(minio.getBucket(), fileName); } /** * 下載文件 */ @GetMapping(value = "/download") public ResponseEntity<byte[]> download(@RequestParam(name = "fileName") String fileName) { ResponseEntity<byte[]> responseEntity = null; ByteArrayOutputStream out = null; InputStream in = null; try{ out = new ByteArrayOutputStream(); in = minioService.getObject(minio.getBucket(),fileName); IOUtils.copy(in, out); //封裝返回值 byte[] bytes = out.toByteArray(); HttpHeaders headers = new HttpHeaders(); try { headers.add("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } headers.setContentLength(bytes.length); headers.setContentType(MediaType.MULTIPART_FORM_DATA); headers.setAccessControlExposeHeaders(Arrays.asList("*")); responseEntity = new ResponseEntity<byte[]>(bytes, headers, HttpStatus.OK); }catch (Exception e){ e.printStackTrace(); }finally { try { if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } if (out != null) { out.close(); } } catch (IOException e) { e.printStackTrace(); } } return responseEntity; } }
到此這篇關(guān)于springboot Minio功能實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)springboot Minio功能內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot+MinIO實(shí)現(xiàn)對(duì)象存儲(chǔ)的示例詳解
- SpringBoot基于Minio實(shí)現(xiàn)分片上傳、斷點(diǎn)續(xù)傳的實(shí)現(xiàn)
- SpringBoot集成MinIO的示例代碼
- SpringBoot + minio實(shí)現(xiàn)分片上傳、秒傳、續(xù)傳功能
- SpringBoot整合minio服務(wù)的示例代碼
- SpringBoot整合Minio的示例代碼
- SpringBoot使用Minio進(jìn)行文件存儲(chǔ)的實(shí)現(xiàn)
- 可能是全網(wǎng)最詳細(xì)的springboot整合minio教程
- Springboot整合minio實(shí)現(xiàn)文件服務(wù)的教程詳解
- SpringBoot整合Minio實(shí)現(xiàn)上傳文件的完整步驟記錄
- SpringBoot整合MinIO實(shí)現(xiàn)文件上傳的方法詳解
- SpringBoot整合minio快速入門(mén)教程(代碼示例)
- SpringBoot+MinIO實(shí)現(xiàn)文件上傳、讀取、下載、刪除的使用示例
相關(guān)文章
聊聊springboot靜態(tài)資源加載的規(guī)則
這篇文章主要介紹了springboot靜態(tài)資源加載的規(guī)則,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12Jmeter壓力測(cè)試簡(jiǎn)單教程(包括服務(wù)器狀態(tài)監(jiān)控)
Jmeter是一個(gè)非常好用的壓力測(cè)試工具。Jmeter用來(lái)做輕量級(jí)的壓力測(cè)試,非常合適,本文詳細(xì)的介紹了Jmeter的使用,感性的可以了解一下2021-11-11很簡(jiǎn)單的Java斷點(diǎn)續(xù)傳實(shí)現(xiàn)原理
這篇文章主要以實(shí)例的方式為大家詳細(xì)介紹了簡(jiǎn)單的Java斷點(diǎn)續(xù)傳實(shí)現(xiàn)原理,感興趣的小伙伴們可以參考一下2016-07-07spring boot微服務(wù)自定義starter原理詳解
這篇文章主要介紹了spring boot微服務(wù)自定義starter原理詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12一文掌握Spring Cookie和Session 是什么及區(qū)別介紹
Cookie和Session都是用于在客戶端和服務(wù)器之間傳遞信息的技術(shù),但它們的工作方式和使用場(chǎng)景有所不同,Cookie是在客戶端保存用戶信息的一種機(jī)制,而Session是在服務(wù)器端保存用戶信息的一種機(jī)制,本文介紹Spring Cookie和Session 是什么,感興趣的朋友一起看看吧2025-01-01JavaSE實(shí)現(xiàn)電影院系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了JavaSE實(shí)現(xiàn)電影院系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08詳解JAVA后端實(shí)現(xiàn)統(tǒng)一掃碼支付:微信篇
本篇文章主要介紹了詳解JAVA后端實(shí)現(xiàn)統(tǒng)一掃碼支付:微信篇,這里整理了詳細(xì)的代碼,有需要的小伙伴可以參考下。2017-01-01