springboot2.X手冊:放棄fastdfs,整合Minio做文件服務(wù)器真香

什么是Minio
Minio是Apcche旗下的一款開源的輕量級文件服務(wù)器,基于對象存儲,協(xié)議是基于Apache License v2.0,開源可用于商務(wù)。
Minio主要用來存儲非結(jié)構(gòu)化的數(shù)據(jù),類似文件,圖片,照片,日志文件,各類備份文件等,按照官網(wǎng)描述,文件的大小從幾KB到5TB。
Minio提供了非常方便,友好的界面,并且文檔也是非常豐富,具體可以參考它的docs
https://docs.min.io/cn/minio-quickstart-guide.html
為什么選擇Minio
以前小編使用阿里的OSS,但是是真的貴,后來使用FastDFS,在友好度上,并不友善,不過這一塊仁者見仁智者見智,不做參考,各位看官按照自己喜歡的就行。
Minio是支持docker安裝的,非常方便,小編現(xiàn)在的私人服務(wù)器上,就是用的docker安裝方式,支持多租戶,高可用用集群多節(jié)點(diǎn)來做,這個上面的網(wǎng)址都有詳細(xì)說明,文檔還是非常豐富的。
整合Minio
"1.0"?>
?xsi:schemaLocation="http://maven.apache.org/POM/4.0.0?http://maven.apache.org/xsd/maven-4.0.0.xsd"
?xmlns="http://maven.apache.org/POM/4.0.0"
?xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
?4.0.0
?
??com.boots
??boots
??1.1.0.RELEASE
?
?boots-module-minio
?boots-module-minio
?http://maven.apache.org
?
??UTF-8
?
?
??
??
???io.minio
???minio
???7.0.2
??
??
??
???com.boots
???module-boots-exception
???2.0.0.RELEASE
??
?
屬性類
/**
?*?All?rights?Reserved,?Designed?By?溪云閣
?*?Copyright:????Copyright(C)?2016-2020
?*/
package?com.boots.module.minio;
import?org.springframework.boot.context.properties.ConfigurationProperties;
import?org.springframework.context.annotation.Configuration;
import?lombok.Data;
/**
?*?minio屬性文件
?*?@author:溪云閣
?*?@date:2020年6月7日
?*/
@Data
@Configuration
@ConfigurationProperties(prefix?=?"boots.module.minio")
public?class?MinioData?{
????/**
?????*?minio地址+端口號
?????*/
????private?String?url;
????/**
?????*?minio用戶名
?????*/
????private?String?accessKey;
????/**
?????*?minio密碼
?????*/
????private?String?secretKey;
????/**
?????*?文件桶的名稱
?????*/
????private?String?bucketName;
}
配置類
在這個配置類里面,是可以拓展的minioClient的,編寫自己喜歡的方法,小編這里為了演示方便,就直接采用原來,其實(shí)都是一樣的,只不過有些人喜歡按照自己的風(fēng)格重寫一遍而已。
/**
?*?All?rights?Reserved,?Designed?By?溪云閣
?*?Copyright:????Copyright(C)?2016-2020
?*/
package?com.boots.module.minio;
import?org.springframework.beans.factory.annotation.Autowired;
import?org.springframework.context.annotation.Bean;
import?org.springframework.context.annotation.Configuration;
import?com.module.boots.exception.CommonRuntimeException;
import?io.minio.MinioClient;
import?lombok.extern.slf4j.Slf4j;
/**
?*?minio客戶端配置
?*?@author:溪云閣
?*?@date:2020年6月7日
?*/
@Slf4j
@Configuration
public?class?MinioConfig?{
????@Autowired
????private?MinioData?minioData;
????/**
?????*?初始化minio客戶端,不用每次都初始化
?????*?@author?溪云閣
?????*?@return?MinioClient
?????*/
????@Bean
????public?MinioClient?minioClient()?{
????????try?{
????????????return?new?MinioClient(minioData.getUrl(),?minioData.getAccessKey(),?minioData.getSecretKey());
????????}
????????catch?(final?Exception?e)?{
????????????log.error("初始化minio出現(xiàn)異常:{}",?e.fillInStackTrace());
????????????throw?new?CommonRuntimeException(e.fillInStackTrace());
????????}
????}
}
配置文件
######配置基本信息######
##配置應(yīng)用名稱
spring.application.name:?boots-minio
##配置時間格式,為了避免精度丟失,全部換成字符串
spring.jackson.timeZone:?GMT+8
spring.jackson.dateFormat:?yyyy-MM-dd?HH:mm:ss
spring.jackson.generator.writeNumbersAsStrings:?true
#?上傳文件總的最大值
spring.servlet.multipart.max-request-size:?10MB
#?單個文件的最大值
spring.servlet.multipart.max-file-size:?10MB
##?minio文件系統(tǒng)
boots.module.minio.url:?http://127.0.0.1:9000
boots.module.minio.accessKey:?minio
boots.module.minio.secretKey:?123456
boots.module.minio.bucketName:?boots
接口類
/**
?*?All?rights?Reserved,?Designed?By?溪云閣
?*?Copyright:????Copyright(C)?2016-2020
?*/
package?com.boots.minio.view.minio.view;
import?java.io.InputStream;
import?java.net.URLEncoder;
import?javax.servlet.http.HttpServletResponse;
import?org.apache.tomcat.util.http.fileupload.IOUtils;
import?org.springframework.beans.factory.annotation.Autowired;
import?org.springframework.http.MediaType;
import?org.springframework.web.bind.annotation.GetMapping;
import?org.springframework.web.bind.annotation.PostMapping;
import?org.springframework.web.bind.annotation.RequestMapping;
import?org.springframework.web.bind.annotation.RequestParam;
import?org.springframework.web.bind.annotation.RestController;
import?org.springframework.web.multipart.MultipartFile;
import?com.boots.module.minio.MinioData;
import?com.module.boots.api.message.ResponseMsg;
import?com.module.boots.api.utils.MsgUtils;
import?com.module.boots.exception.CommonRuntimeException;
import?io.minio.MinioClient;
import?io.minio.ObjectStat;
import?io.minio.PutObjectOptions;
import?io.swagger.annotations.Api;
import?io.swagger.annotations.ApiOperation;
import?lombok.SneakyThrows;
/**
?*?minio上傳,下載,刪除接口
?*?@author:溪云閣
?*?@date:2020年6月7日
?*/
@SuppressWarnings("deprecation")
@Api(tags?=?{?"web服務(wù):minio上傳,下載,刪除接口"?})
@RestController
@RequestMapping("view/minio")
public?class?MinioView?{
????@Autowired
????private?MinioClient?minioClient;
????@Autowired
????private?MinioData?minioData;
????/**
?????*?下載文件
?????*?@author?溪云閣??void
?????*/
????@ApiOperation(value?=?"下載文件")
????@GetMapping(value?=?"/download")
????@SneakyThrows(Exception.class)
????public?void?download(@RequestParam("fileName")?String?fileName,?HttpServletResponse?response)?{
????????InputStream?in?=?null;
????????final?ObjectStat?stat?=?minioClient.statObject(minioData.getBucketName(),?fileName);
????????response.setContentType(stat.contentType());
????????response.setHeader("Content-Disposition",?"attachment;filename="?+?URLEncoder.encode(fileName,?"UTF-8"));
????????in?=?minioClient.getObject(minioData.getBucketName(),?fileName);
????????IOUtils.copy(in,?response.getOutputStream());
????????in.close();
????}
????/**
?????*?上傳文件
?????*?@author?溪云閣
?????*?@param?file
?????*?@return
?????*?@throws?Exception?ResponseMsg
?????*/
????@ApiOperation(value?=?"上傳文件")
????@PostMapping(value?=?"/upload")
????@SneakyThrows(Exception.class)
????public?ResponseMsg?upload(@RequestParam("file")?MultipartFile?file)?throws?Exception?{
????????if?(file.isEmpty())?{
????????????throw?new?CommonRuntimeException("上傳文件不能為空");
????????}?else?{
????????????//?得到文件流
????????????final?InputStream?is?=?file.getInputStream();
????????????//?文件名
????????????final?String?fileName?=?file.getOriginalFilename();
????????????//?把文件放到minio的boots桶里面
????????????minioClient.putObject(minioData.getBucketName(),?fileName,?is,?new?PutObjectOptions(is.available(),?-1));
????????????//?關(guān)閉輸入流
????????????is.close();
????????????return?MsgUtils.buildSuccessMsg("上傳成功");
????????}
????}
????/**
?????*?刪除文件
?????*?@author?溪云閣
?????*?@param?fileName
?????*?@return?ResponseMsg
?????*/
????@ApiOperation(value?=?"刪除文件")
????@GetMapping(value?=?"/delete",?produces?=?MediaType.APPLICATION_JSON_UTF8_VALUE)
????@SneakyThrows(Exception.class)
????public?ResponseMsg?delete(@RequestParam("fileName")?String?fileName)?{
????????minioClient.removeObject(minioData.getBucketName(),?fileName);
????????return?MsgUtils.buildSuccessMsg("刪除成功");
????}
}
測試
運(yùn)行后,我們查看接口文檔,已經(jīng)寫好3個方法了
作者溪云閣,專注編程教學(xué),架構(gòu),JAVA,Python,微服務(wù),機(jī)器學(xué)習(xí)等領(lǐng)域,歡迎關(guān)注,一起學(xué)習(xí)。

好文章,我在看
好文章,我在看
評論
圖片
表情
