SpringBoot整合Minio實現(xiàn)圖片上傳功能
minio服務器
minio服務器主要功能:保存文件【可以圖片、ppt、xsl】
1、MinIo簡介
Minio 是個基于 Golang 編寫的開源對象存儲套件,雖然輕量,卻擁有著不錯的性能。
官網地址:MinIO | High Performance, Kubernetes Native Object Storage
中文官網地址:http://www.minio.org.cn
中文文檔對應的是上個版本,新版本中有些內容已發(fā)生了變化,所以最好是看英文文檔。何為對象存儲?
對象存儲服務( Object Storage Service,OSS )是一種海量、安全、低成本、高可靠的云存儲服務,適合存放任意類型的文件。容量和處理能力彈性擴展,多種存儲類型供選擇,全面優(yōu)化存儲成本。
對于中小型企業(yè),如果不選擇存儲上云,那么 Minio 是個不錯的選擇,麻雀雖小,五臟俱全。
2、安裝MinIo
a、下載安裝
Windows 版下載地址:windows-amd64 版按慣例,我們將下載的 minio.exe 放在 C:\ProgramFiles\MinIO 下,因此,MINIO_HOME 就是 C:\ProgramFiles\MinIO
b、安裝minio
1、下載 MinIO
安裝wget:
yum -y install wget #由于需要用到wget命令,所以要先安裝wget
創(chuàng)建minio目錄:
mkdir -p /usr/local/minio
mkdir -p /usr/local/minio/bin
mkdir -p /usr/local/minio/data
進入/usr/local/minio/bin執(zhí)行如下命令:
wget https://dl.minio.org.cn/server/minio/release/linux-amd64/minio
賦予它可執(zhí)行權限: 進入到/usr/local/minio/bin中執(zhí)行如下命令
chmod +x minio
在usr/local下創(chuàng)建minio文件夾,并在minio文件里面創(chuàng)建bin和data目錄,把下載好的minio文件拷貝到bin目錄里面
2、將 minio 添加成 Linux 的服務
cat > /etc/systemd/system/minio.service << EOF [Unit] Description=Minio Wants=network-online.target After=network-online.target AssertFileIsExecutable=/usr/local/minio/bin/minio [Service] WorkingDirectory=/usr/local/minio/ PermissionsStartOnly=true ExecStart=/usr/local/minio/bin/minio server /usr/local/minio/data ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s QUIT $MAINPID PrivateTmp=true [Install] WantedBy=multi-user.target EOF
這樣就可以使用 systemctl 啟停 minio
systemctl start minio # 啟動 systemctl stop minio # 停止 systemctl enable minio #設置自動開啟 systemctl status minio # 查看服務運行狀態(tài)
c、啟動運行
輸入用戶名/密碼 minioadmin/minioadmin 可以進入 web 管理系統(tǒng):
d、創(chuàng)建桶
剛打開的時候,是沒有bucket桶,可以手動或者通過java代碼來創(chuàng)建一個桶。
創(chuàng)建的桶默認的權限時private私有的,外部不能訪問,你可以修改桶的屬性,點擊manage,找到Access Policy,修改權限為public即可。
e、上傳文件到桶
f、關停 MinIO
通過命令行啟動 MioIO 后,命令行窗口就被占用了。關閉命令行窗口即關閉 MioIO ,也可以使用 ctrl + c 關閉
3、Springboot整合minio
添加minio整合所需的依賴
com.squareup.okhttp3 okhttp 4.8.1 io.minio minio 8.3.9
設置minio服務器信息
#minio配置 minio: endpoint: http://127.0.0.1:9000 accesskey: minioadmin secretKey: minioadmin
創(chuàng)建minion配置類
/**
* minio配置類
*/
@Configuration
@Data
@ConfigurationProperties(prefix = “minio”)
public class MinIoConfig {
private String endpoint;
private String accesskey;
private String secretKey;
/**
* 創(chuàng)建MinioClient對象
* @return
* @throws Exception
*/
@Bean
public MinioClient minioClient() throws Exception {
return MinioClient.builder().endpoint(endpoint)
.credentials(accesskey, secretKey).build();
}
}
測試整合結果
4、案例:用戶頭像上傳
文件上傳是日常項目中非常常規(guī)且常用的一個功能。主要的功能就是將客戶端的文件保存到服務器,以便于資源的“瀏覽”。怎么實現(xiàn)文件上傳呢?SpringMvc中提供了對應的文件上傳解析器,按照給定要求,在SpringMvc的環(huán)境下,我們可以很方便的實現(xiàn)上傳功能。
文件上傳注意事項
form 表單的 enctype 取值必須是:multipart/form-data(默認值是:application/x-www-form-urlencoded)
method 屬性取值必須是 post
提供一個文件選擇域,HTML5原生html中,利用
不過,元素file標簽,外觀單一,企業(yè)級應用中更多的會選擇使用外觀更加豐富的一些“組件”,比如在element-ui的el-upload組件
el-upload上傳組件常用屬性
<el-upload
class="avatar-uploader" action="#"
:show-file-list="false"
:before-upload="beforeAvatarUpload"
:http-request="doUploadImage">
<img v-if="imageUrl" :src="imageUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
文件上傳組件常用屬性
- action:設置文件上傳控制器url地址,屬于同步請求提交方式。必備屬性
- http-request:設置實現(xiàn)上傳請求發(fā)送的自定義函數名,若要實現(xiàn)自定義上傳方式,必須使用http-requeset
- :before-upload:處理圖片上傳過程的鉤子,該屬性處理圖片上傳之前的功能。其值設置一個函數,參考上述案例代碼:可以判斷上傳文件的格式和大小
axios.post提交上傳請求
因為文件上傳的格式必須是:multipart/formdata格式,所以axios.post處理文件上傳時,參數較以前的使用,略有變化,具體代碼參考如下:
doUpload(file){//file 獲取用戶選擇封面圖片
console.log("file",file.file);
//將用戶選擇的圖片內容封裝為formdata類型,才能交給控制器處理
let formData=new FormData();
formData.append("face",file.file);
axios.post("/user/do-upload",formData,{contentType:'multipart/form-data'})
.then(resp=>{
if(resp.data.status===200){
alert("文件上傳成功"+resp.data.msg);
}else{
alert("文件上傳失敗");
}
});
代碼解讀
FormData是JavaScript提供的一個對象類型,作用封裝multipart/form-data格式數據。 formData對象的append()方法,可以以key:value格式存入數據,控制器在后臺以key獲取對應的值 contentType:'multipart/form-data'設置axios.post提交數據格式。 因為axios.post默認提交格式是jsonstring,此處需要手動顯式設置數據提交格式:contentType:'multipart/form-data'
Controller控制器后端處理上傳請求
Springmvc處理文件上傳請求時,因為請求體提交數據的格式不再是傳統(tǒng)的jsonstring或querystring格式,所以,控制器在處理上傳請求前,需要先配置文件上傳解析器。具體流程如下所示:
pom.xml導入文件解析器依賴
commons-fileupload commons-fileupload 1.4 commons-io commons-io 2.10.0
pplication.yml配置文件上傳解析器
Spring: servlet: multipart: max-file-size: 30MB #單個文件的最大上限 max-request-size: 60MB #單個請求的文件總大小上限
Controller處理上傳請求
@PostMapping(“/do-upload”)
public ResponseResult doUploadImage(
@RequestParam(value = “aa”,required = true,defaultValue = “”) MultipartFile image
) {
log.info(“用戶提交的圖書:{}”,image);
//保存文件到minio服務器即可
String bucketName=“woniu-mall”;
//1-1 創(chuàng)建桶
minIoUtil.createBucket(bucketName);
//1-2 上傳文件
String oldName = image.getOriginalFilename();
//文件名稱
String firstName = UUID.randomUUID().toString().replace(“-”, “”);
//文件后綴名
String lastName = oldName.substring(oldName.lastIndexOf(“.”));
//新的文件名稱
String fileName=“goods/”+firstName+ lastName;
minIoUtil.putObject(bucketName,image,fileName,image.getContentType());
//1-3 獲取外鏈
String objectUrl = minIoUtil.getObjectUrl(bucketName, fileName);
return new ResponseResult(200,“上傳成功!”,objectUrl);
}處理上傳后的響應結果
Minio操作工具類
基于Springmvc整合Minio時,我們在MinioConfig中注入過MinioClient對象,而MinioClient對象就是操作minio服務器的核心對象,該對象提供了在minio服務器上創(chuàng)建桶、上傳文件,分享外鏈給用戶使用的功能。為了便于日常的開發(fā)使用,我們將這些功能封裝成MinioUtil工具類,開發(fā)人員結合開發(fā)需求,調用對應方法完成需求即可。工具類的具體代碼如下所示:
@Slf4j //日志管理工具
@Component
public class MinIoUtil {
@Autowired
private MinioClient minioClient;
/**
* 創(chuàng)建桶
* @param bucketName 桶名
*/
public void createBucket(String bucketName) {
BucketExistsArgs bucketExistsArgs = BucketExistsArgs.builder().bucket(bucketName).build();
MakeBucketArgs makeBucketArgs = MakeBucketArgs.builder().bucket(bucketName).build();
try {
if (minioClient.bucketExists(bucketExistsArgs)) {
return;
}
minioClient.makeBucket(makeBucketArgs);
} catch (Exception e) {
//跟sout作用一樣,在控制臺輸出程序執(zhí)行信息
log.error("創(chuàng)建桶失?。?, e.getMessage());
throw new RuntimeException(e);
}
}
/**
* 通過 MultipartFile ,上傳文件
*
* @param bucketName 存儲桶
* @param file 文件
* @param objectName 對象名(文件名)存入桶時,文件新命名:唯一不重復
* @param contentType 文件類型 文件上傳時格式
*/
public ObjectWriteResponse putObject(String bucketName, MultipartFile file, String objectName, String contentType) {
try {
//調用創(chuàng)建桶方法
createBucket(bucketName);
//獲取文件輸入流
InputStream inputStream = file.getInputStream();
PutObjectArgs args = PutObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.contentType(contentType)
.stream(inputStream, inputStream.available(), -1)
.build();
return minioClient.putObject(args);
} catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException |
InvalidResponseException | IOException | NoSuchAlgorithmException |
ServerException | XmlParserException e) {
throw new RuntimeException(e);
}
}
/**
* 獲取?件外鏈
*
* @param bucketName bucket名稱
* @param objectName ?件名稱
* @param expires 過期時間 <=7
* @param timeUnit 有效期時間單位
*/
public String getObjectUrl(String bucketName, String objectName, Integer expires, TimeUnit timeUnit) {
GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder()
.method(Method.GET)
.bucket(bucketName)
.object(objectName)
.expiry(expires,timeUnit)// 單位:默認是,秒
.build();
try {
String url=minioClient.getPresignedObjectUrl(args);
return getImgUrl(url);
} catch (ErrorResponseException | InsufficientDataException | InternalException |
InvalidResponseException | InvalidKeyException | NoSuchAlgorithmException |
IOException | XmlParserException | ServerException e) {
throw new RuntimeException(e);
}
}
/**
* 獲取?件外鏈
*
* @param bucketName bucket名稱
* @param objectName ?件名稱
*/
public String getObjectUrl(String bucketName, String objectName) {
GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder()
.method(Method.GET)
.bucket(bucketName)
.object(objectName)// 單位:默認是,秒
.build();
try {
String url=minioClient.getPresignedObjectUrl(args);
return getImgUrl(url);
} catch (ErrorResponseException | InsufficientDataException | InternalException |
InvalidResponseException | InvalidKeyException | NoSuchAlgorithmException |
IOException | XmlParserException | ServerException e) {
throw new RuntimeException(e);
}
}
/**
* 處理圖片上傳后外鏈地址
* 只獲得url端口號以后的內容
* @param urlStr
* @return
*/
private String getImgUrl(String urlStr){
if(urlStr.isEmpty()){
return "";
}
Pattern pattern = Pattern.compile("\\?"); //通過正則找字符串中的?
Matcher matcher = pattern.matcher(urlStr); //正則表達式比對器
if (matcher.find()){
int seartIndex = matcher.end(); //獲得?開始的位置
if(seartIndex!=-1){
urlStr=urlStr.substring(0,seartIndex-1);
}
}
Pattern pattern1 = Pattern.compile(":\\d{1,5}"); //通過正則找字符串中的端口
Matcher matcher1 = pattern1.matcher(urlStr); //正則表達式比對器
if (matcher1.find()){
int endIndex = matcher1.end(); //獲得正則表達式規(guī)則結束字符串的位置
if(endIndex!=-1){
return urlStr.substring(endIndex);
}
}
return "";
}
}
5、常見問題
商品列表:表格圖片無法正常顯示問題
用戶頭像顯示問題:element組件中el-table默認循環(huán)時,沒有給每一行指定key,用于標識數據渲染的位置,所以在使用el-avatar顯示圖片時,會出現(xiàn)圖片url地址正確的情況下,圖片無法正常顯示問題,
解決方案有以下兩種:
修改商品信息時:設置圖片回顯
在商品信息管理時,我們可能會對商品的封面照片進行修改。那么當我們點擊“修改”按鈕進入到商品修改頁面時,一般情況,需要默認顯示商品“舊”圖片的信息。el-upload組件如何設置默認顯示的圖片呢?在修改頁面初始化數據時,給el-upload組件的imageUrl賦值即可完成
以上就是SpringBoot整合Minio實現(xiàn)圖片上傳功能的詳細內容,更多關于SpringBoot Minio圖片上傳的資料請關注腳本之家其它相關文章!
相關文章
springboot對接minio的webhook完整步驟記錄
Minio是一款開源的對象存儲服務,它致力于為開發(fā)者提供簡單、高性能、高可用的云存儲解決方案,下面這篇文章主要給大家介紹了關于springboot對接minio的webhook的相關資料,需要的朋友可以參考下2024-07-07
JAVA通過HttpURLConnection 上傳和下載文件的方法
這篇文章主要介紹了JAVA通過HttpURLConnection 上傳和下載文件的方法,非常具有實用價值,需要的朋友可以參考下2017-09-09
myeclipse創(chuàng)建servlet_動力節(jié)點Java學院整理
這篇文章主要為大家詳細介紹了myeclipse創(chuàng)建servlet的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07
Spring框架的環(huán)境搭建和測試實現(xiàn)
這篇文章主要介紹了Spring框架的環(huán)境搭建和測試實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-10-10
Spring使用Configuration注解管理bean的方式詳解
在Spring的世界里,Configuration注解就像是一位細心的園丁,它的主要職責是在這個繁花似錦的園子里,幫助我們聲明和管理各種各樣的bean,本文給大家介紹了在Spring中如何優(yōu)雅地管理你的bean,需要的朋友可以參考下2024-05-05

