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: minioadmin3.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,如果沒有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 要讀取的長度
* @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);
}
/**
* 通過流上傳文件
*
* @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);
}
/**
* 獲取文件信息, 如果拋出異常則說明文件不存在
*
* @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("批量刪除失?。rror:{0}", e);
}
});
}
/**
* 獲取文件外鏈
*
* @param bucketName 存儲(chǔ)桶名稱
* @param objectName 文件名
* @param expires 過期時(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)容請搜索腳本之家以前的文章或繼續(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快速入門教程(代碼示例)
- SpringBoot+MinIO實(shí)現(xiàn)文件上傳、讀取、下載、刪除的使用示例
相關(guān)文章
聊聊springboot靜態(tài)資源加載的規(guī)則
這篇文章主要介紹了springboot靜態(tài)資源加載的規(guī)則,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12
Jmeter壓力測試簡單教程(包括服務(wù)器狀態(tài)監(jiān)控)
Jmeter是一個(gè)非常好用的壓力測試工具。Jmeter用來做輕量級(jí)的壓力測試,非常合適,本文詳細(xì)的介紹了Jmeter的使用,感性的可以了解一下2021-11-11
很簡單的Java斷點(diǎn)續(xù)傳實(shí)現(xiàn)原理
這篇文章主要以實(shí)例的方式為大家詳細(xì)介紹了簡單的Java斷點(diǎn)續(xù)傳實(shí)現(xiàn)原理,感興趣的小伙伴們可以參考一下2016-07-07
spring boot微服務(wù)自定義starter原理詳解
這篇文章主要介紹了spring boot微服務(wù)自定義starter原理詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12
一文掌握Spring Cookie和Session 是什么及區(qū)別介紹
Cookie和Session都是用于在客戶端和服務(wù)器之間傳遞信息的技術(shù),但它們的工作方式和使用場景有所不同,Cookie是在客戶端保存用戶信息的一種機(jī)制,而Session是在服務(wù)器端保存用戶信息的一種機(jī)制,本文介紹Spring Cookie和Session 是什么,感興趣的朋友一起看看吧2025-01-01
JavaSE實(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

