什么是MinIO?
MinIO 是一款高性能、分布式的對(duì)象存儲(chǔ)系統(tǒng). 它是一款軟件產(chǎn)品, 可以100%的運(yùn)行在標(biāo)準(zhǔn)硬件。即X86等低成本機(jī)器也能夠很好的運(yùn)行MinIO。
根據(jù)minio依賴實(shí)現(xiàn)文件上傳下載
1.導(dǎo)入環(huán)境所需要的依賴
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.3</version>
<relativePath/>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--minio 8.2.2沒有報(bào)依賴異常 新版報(bào)異常-->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.2.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.26</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
2.application.yml中進(jìn)行minio的配置
minio:
endpoint: http://192.168.233.123:9000 #Minio服務(wù)所在地址
accessKey: minioadmin #連接Minio用戶名
secretKey: minioadmin #連接Minio密碼
bucketName: testadmin #Minio數(shù)據(jù)桶名稱
3.MinIoConfig.class 配置類?
此類主要做一些連接Minio實(shí)例化對(duì)象的配置
import io.minio.MinioClient;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author: yujie.li
* @description
* @date 2023/7/18
*/
@Data
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinIoConfig {
/**
* 訪問密鑰
*/
@Value("${minio.accessKey}")
private String accessKey;
/**
* 密鑰
*/
@Value("${minio.secretKey}")
private String secretKey;
/**
* 訪問api Url
*/
@Value("${minio.endpoint}")
private String endpoint;
/**
* 捅名稱
*/
@Value("${minio.bucketName}")
private String bucketName;
/**
* 創(chuàng)建MinIo客戶端
*
* @return
*/
@Bean
public MinioClient minioClient() {
return MinioClient.builder()
.endpoint(endpoint)
.credentials(accessKey, secretKey)
.build();
}
}
?4.AjaxResult.class 實(shí)體類
此類對(duì)數(shù)據(jù)結(jié)果進(jìn)行封裝,返回報(bào)文
import java.util.HashMap;
/**
* 數(shù)據(jù)結(jié)果封裝體 AjaxResult
*
* @author yujie.li
*/
public class AjaxResult extends HashMap<String, Object>
{
private static final long serialVersionUID = 1L;
/** 狀態(tài)碼 */
public static final String CODE_TAG = "code";
/** 返回內(nèi)容 */
public static final String MSG_TAG = "msg";
/** 數(shù)據(jù)對(duì)象 */
public static final String DATA_TAG = "data";
/**
* 初始化一個(gè)AjaxResult 對(duì)象
*/
public AjaxResult()
{
}
/**
* 初始化一個(gè)AjaxResult 對(duì)象
*
* @param code 狀態(tài)碼
* @param msg 返回內(nèi)容
*/
public AjaxResult(int code, String msg)
{
super.put(CODE_TAG, code);
super.put(MSG_TAG, msg);
}
/**
* 初始化一個(gè)AjaxResult 對(duì)象
*
* @param code 狀態(tài)碼
* @param msg 返回內(nèi)容
* @param data 數(shù)據(jù)對(duì)象
*/
public AjaxResult(int code, String msg, Object data)
{
super.put(CODE_TAG, code);
super.put(MSG_TAG, msg);
if (!(data == null))
{
super.put(DATA_TAG, data);
}
}
/**
* 返回默認(rèn)成功消息
*
* @return 成功消息
*/
public static AjaxResult success()
{
return AjaxResult.success("操作成功");
}
/**
* 返回成功消息
*
* @param msg 返回內(nèi)容
* @return 成功消息
*/
public static AjaxResult success(String msg)
{
return AjaxResult.success(msg, null);
}
/**
* 返回成功數(shù)據(jù)
* @param data 數(shù)據(jù)對(duì)象
* @return
*/
public static AjaxResult success(Object data)
{
return AjaxResult.success("操作成功", data);
}
/**
* 初始化一個(gè)返回成功消息AjaxResult對(duì)象
*
* @param msg 返回內(nèi)容
* @param data 數(shù)據(jù)對(duì)象
* @return 成功消息
*/
public static AjaxResult success(String msg, Object data)
{
return new AjaxResult(HttpStatus.SUCCESS, msg, data);
}
/**
* 返回默認(rèn)錯(cuò)誤消息
*
* @return
*/
public static AjaxResult error()
{
return AjaxResult.error("操作失敗");
}
/**
* 返回錯(cuò)誤消息
*
* @param msg 返回內(nèi)容
* @return 警告消息
*/
public static AjaxResult error(String msg)
{
return AjaxResult.error(msg, null);
}
/**
* 返回錯(cuò)誤數(shù)據(jù)
*
* @param code 狀態(tài)碼
* @param msg 返回內(nèi)容
* @return 警告消息
*/
public static AjaxResult error(int code, String msg)
{
return new AjaxResult(code, msg, null);
}
/**
* 初始化一個(gè)返回錯(cuò)誤消息AjaxResult對(duì)象
*
* @param msg 返回內(nèi)容
* @param data 數(shù)據(jù)對(duì)象
* @return 警告消息
*/
public static AjaxResult error(String msg, Object data)
{
return new AjaxResult(HttpStatus.ERROR, msg, data);
}
}
?5.HttpStatus.class 實(shí)體類
此類對(duì)返回Http狀態(tài)碼進(jìn)行封裝
/**
* 返回HTTP狀態(tài)碼
*
* @author yujie.li
*/
public class HttpStatus {
/**
* 操作成功
*/
public static final int SUCCESS = 200;
/**
* 對(duì)象創(chuàng)建成功
*/
public static final int CREATED = 201;
/**
* 請(qǐng)求已經(jīng)被接受
*/
public static final int ACCEPTED = 202;
/**
* 操作已經(jīng)執(zhí)行成功,但是沒有返回?cái)?shù)據(jù)
*/
public static final int NO_CONTENT = 204;
/**
* 資源已被移除
*/
public static final int MOVED_PERM = 301;
/**
* 重定向
*/
public static final int SEE_OTHER = 303;
/**
* 資源未被修改
*/
public static final int NOT_MODIFIED = 304;
/**
* 參數(shù)列表錯(cuò)誤(缺少、格式不匹配)
*/
public static final int BAD_REQUEST = 400;
/**
* 未授權(quán)
*/
public static final int UNAUTHORIZED = 401;
/**
* 訪問受限,授權(quán)過期
*/
public static final int FORBIDDEN = 403;
/**
* 資源,服務(wù)未找到
*/
public static final int NOT_FOUND = 404;
/**
* 未被允許http方法
*/
public static final int BAD_METHOD = 405;
/**
* 資源沖突,或者資源被鎖
*/
public static final int CONFLICT = 409;
/**
* 不支持媒體類型數(shù)據(jù)
*/
public static final int UNSUPPORTED_TYPE = 415;
/**
* 系統(tǒng)內(nèi)部錯(cuò)誤
*/
public static final int ERROR = 500;
/**
* 未實(shí)現(xiàn)相應(yīng)接口
*/
public static final int NOT_IMPLEMENTED = 501;
}
6.?ServletUtils.class 配置類
此類返回 JSON 數(shù)據(jù)的方法
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class ServletUtils {
public static void renderString(HttpServletResponse response, String json) throws IOException {
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
try (PrintWriter writer = response.getWriter()) {
writer.write(json);
writer.flush();
}
}
}
7.MinIoUtil.class 工具類
?此工具類中包含上傳與下載的方法
import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.errors.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author: yujie.li
* @description
* @date 2023/7/18
*/
@Component
public class MinIOUtil {
@Autowired
private MinioClient minioClient;
/**
* 捅名稱
*/
@Value("${minio.bucketName}")
private String bucketName;
/**
* putObject上傳文件
*
* @param file 文件
* @return filePath
*/
public String putObject(MultipartFile file) throws IOException, ServerException, InsufficientDataException, InternalException, InvalidResponseException, InvalidKeyException, NoSuchAlgorithmException, XmlParserException, ErrorResponseException {
//文件名
String originalFilename = file.getOriginalFilename();
//文件流
InputStream inputStream = file.getInputStream();
//文件大小
long size = file.getSize();
//文件路徑
String filePath = createFilePath(originalFilename);
System.out.println(filePath+"\t文件路徑");
//存儲(chǔ)方法 putObject
minioClient.putObject(PutObjectArgs.builder()
.bucket(bucketName)
.object(filePath)
.stream(inputStream, size, -1)
.contentType(file.getContentType())
.build());
return filePath;
}
/**
* 下載文件
*
* @param filePath 文件路徑
*/
public void getObject(HttpServletResponse httpServletResponse, String filePath) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
String fileName = getFileName(filePath);
InputStream inputStream = minioClient.getObject(GetObjectArgs.builder()
.bucket(bucketName)
.object(filePath)
.build());
downloadFile(httpServletResponse, inputStream, fileName);
}
/**
* 獲取文件路徑
*
* @param originalFilename 原始文件名稱
* @return FilePath
*/
public String createFilePath(String originalFilename) {
return new SimpleDateFormat("yyyy/MM/dd").format(new Date()) + "/" + originalFilename;
}
/**
* 根據(jù)文件路徑獲取文件名稱
*
* @param filePath 文件路徑
* @return 文件名
*/
public String getFileName(String filePath) {
String[] split = StringUtils.split(filePath, "/");
return split[split.length - 1];
}
/**
* 下載文件
*
* @param httpServletResponse httpServletResponse
* @param inputStream inputStream
* @param fileName 文件名
* @throws IOException IOException
*/
public void downloadFile(HttpServletResponse httpServletResponse, InputStream inputStream, String fileName) throws IOException {
//設(shè)置響應(yīng)頭信息,告訴前端瀏覽器下載文件
httpServletResponse.setContentType("application/octet-stream;charset=UTF-8");
httpServletResponse.setCharacterEncoding("UTF-8");
httpServletResponse.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
//獲取輸出流進(jìn)行寫入數(shù)據(jù)
OutputStream outputStream = httpServletResponse.getOutputStream();
// 將輸入流復(fù)制到輸出流
byte[] buffer = new byte[4096];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
// 關(guān)閉流資源
inputStream.close();
outputStream.close();
}
}
8.?MinioController.class 控制類
import com.alibaba.fastjson2.JSON;
import com.lyj.msg.AjaxResult;
import com.lyj.msg.HttpStatus;
import com.lyj.utils.MinIOUtil;
import com.lyj.utils.ServletUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author yujie.li
* @description
* @date 2023/7/18
*/
@RestController
@Slf4j
public class MinioController {
@Autowired
private MinIOUtil minioUtil;
@PostMapping("/upload")
public AjaxResult upload(@RequestPart MultipartFile file) {
String filePath;
try {
filePath = minioUtil.putObject(file);
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error("上傳失敗");
}
return AjaxResult.success(filePath);
}
@GetMapping("/download")
public void download(HttpServletResponse response, @RequestParam(value = "filepath") String filepath) throws IOException {
try {
minioUtil.getObject(response, filepath);
} catch (Exception e) {
e.printStackTrace();
log.error("下載失敗", e);
response.reset();
AjaxResult result = new AjaxResult(HttpStatus.ERROR, e.getMessage());
String json = JSON.toJSONString(result);
ServletUtils.renderString(response, json);
}
}
}
ps.遇到的坑
1.需要將自己所創(chuàng)建的Buckets桶權(quán)限設(shè)置為public
2.桶的名稱需要與yml配置類中bucketName一致
3.?測(cè)試下載接口時(shí),傳遞的參數(shù)值為桶中的文件路徑即可,不需要在加桶的名稱,例如(testadmin/1.png)
文章來源:http://www.zghlxwxcb.cn/news/detail-723667.html
尾注:每一行代碼 都是改變世界的能量 愿你每一次的運(yùn)行 都是發(fā)自內(nèi)心的快樂文章來源地址http://www.zghlxwxcb.cn/news/detail-723667.html
到了這里,關(guān)于SpringBoot整合Minio(實(shí)現(xiàn)上傳與下載)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!