導入依賴
<!--minio--><dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.0.3</version></dependency>
yml配置(默認配置)
max-file-size: 200MB 設置文件最大上傳大小為200MB,超過則返回錯誤信息并拒絕文件上傳
max-request-size: 100MB 這個配置項指定了整個請求的最大大小限制,包括所有文件和表單數據的大小。如果請求大小超過這個限制,將會拒絕請求并返回錯誤。
enabled:true?這個配置項指定了文件上傳功能是否啟用,設置為true
表示啟用文件上傳功能,設置為false
表示禁用文件上傳功能。當禁用文件上傳功能時,任何文件上傳請求都將被拒絕。
minion的配置和oss很像,都是這幾個需要注入的值
spring:# 配置文件上傳大小限制servlet:multipart:max-file-size: 200MBmax-request-size: 200MBenabled: true
minio:endpoint: http://127.0.0.1:9000accessKey: minioadminsecretKey: minioadminbucketName: bucket-qhj
該圖和上面minio配置對應
補充:由于每次啟動minio.exe要進入對應目錄,很麻煩,所以可以寫個批處理文件.bat
@echo off
:這是批處理文件的第一行,表示關閉命令回顯,即不在命令執行前顯示命令本身。
echo.
:顯示一個空行,這樣可以讓輸出信息更加清晰。
echo [信息] 運行MinIO文服務器。
:輸出提示信息,告訴用戶即將運行MinIO文服務器。
title minio
:設置窗口標題為 "minio"。D:? 代表進入D盤
cd D:\Program Files\minio 代表進入你minio.exe存放的根目錄
minio.exe server D:\MineFile\zuoye\xm\minioFile --console-address ":9999"?在D:\MineFile\zuoye\xm\minioFile文件夾執行,并且增加額外端口’9999‘
@echo off
echo.
echo [信息] 運行MinIO文服務器。
echo.title minioD:
cd D:\Program Files\miniominio.exe server D:\MineFile\zuoye\xm\minioFile --console-address ":9999"
pause
配置類
注入客戶端配置放入bean
@Data注解:
? ? ? ? 自動生成java類的標準方法,getter,setter,toString,equals,hashCode方法等
@Component
? ? ? ? 這個注解標識 MinIoClientConfig 類作為一個組件(bean)交給 Spring 容器管理,這樣其他地方就可以通過依賴注入來使用該類。
value注解
????????裝配yml配置文件中的值
@Bean注解
????????把minioClient方法注入容器交給 Spring 容器管理
@Data
@Component
public class MinIoClientConfig {@Value("${minio.endpoint}")private String endpoint;@Value("${minio.accessKey}")private String accessKey;@Value("${minio.secretKey}")private String secretKey;/*** 注入minio 客戶端* @return*/@Beanpublic MinioClient minioClient(){return MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();}}
實體類
用于工具類的調用暫存
@Data
public class ObjectItem {private String objectName;private Long size;
}
工具類
根據實體類
/*** @description: minio工具類* @version:3.0*/
@Component
public class MinioUtilS {@Autowiredprivate MinioClient minioClient;@Value("${minio.bucketName}")private String bucketName;/*** description: 判斷bucket是否存在,不存在則創建** @return: void*/public void existBucket(String name) {try {boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(name).build());if (!exists) {minioClient.makeBucket(MakeBucketArgs.builder().bucket(name).build());}} catch (Exception e) {e.printStackTrace();}}/*** 創建存儲bucket* @param bucketName 存儲bucket名稱* @return Boolean*/public Boolean makeBucket(String bucketName) {try {minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());} catch (Exception e) {e.printStackTrace();return false;}return true;}/*** 刪除存儲bucket* @param bucketName 存儲bucket名稱* @return Boolean*/public Boolean removeBucket(String bucketName) {try {minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());} catch (Exception e) {e.printStackTrace();return false;}return true;}/*** description: 上傳文件** @param multipartFile* @return: java.lang.String*/public List<String> upload(MultipartFile[] multipartFile) {List<String> names = new ArrayList<>(multipartFile.length);for (MultipartFile file : multipartFile) {String fileName = file.getOriginalFilename();String[] split = fileName.split("\\.");if (split.length > 1) {fileName = split[0] + "_" + System.currentTimeMillis() + "." + split[1];} else {fileName = fileName + System.currentTimeMillis();}InputStream in = null;try {in = file.getInputStream();minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(fileName).stream(in, in.available(), -1).contentType(file.getContentType()).build());} catch (Exception e) {e.printStackTrace();} finally {if (in != null) {try {in.close();} catch (IOException e) {e.printStackTrace();}}}names.add(fileName);}return names;}/*** description: 下載文件** @param fileName* @return: org.springframework.http.ResponseEntity<byte [ ]>*/public ResponseEntity<byte[]> download(String fileName) {ResponseEntity<byte[]> responseEntity = null;InputStream in = null;ByteArrayOutputStream out = null;try {in = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(fileName).build());out = new ByteArrayOutputStream();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.APPLICATION_OCTET_STREAM);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;}/*** 查看文件對象* @param bucketName 存儲bucket名稱* @return 存儲bucket內文件對象信息*/public List<ObjectItem> listObjects(String bucketName) {Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).build());List<ObjectItem> objectItems = new ArrayList<>();try {for (Result<Item> result : results) {Item item = result.get();ObjectItem objectItem = new ObjectItem();objectItem.setObjectName(item.objectName());objectItem.setSize(item.size());objectItems.add(objectItem);}} catch (Exception e) {e.printStackTrace();return null;}return objectItems;}/*** 批量刪除文件對象* @param bucketName 存儲bucket名稱* @param objects 對象名稱集合*/public Iterable<Result<DeleteError>> removeObjects(String bucketName, List<String> objects) {List<DeleteObject> dos = objects.stream().map(e -> new DeleteObject(e)).collect(Collectors.toList());Iterable<Result<DeleteError>> results = minioClient.removeObjects(RemoveObjectsArgs.builder().bucket(bucketName).objects(dos).build());return results;}
}
控制器類
返回可訪問的url
@RestController:
???????? 這個注解表示該類是一個 RESTful 服務的控制器,用于處理 HTTP 請求并返回 JSON 格式的響應。
@Slf4j:
????????這是 lombok 提供的注解,用于自動生成日志 Logger 對象,可以通過 log 對象進行日志輸出。
@RestController
@Slf4j
@RequestMapping("/fileSave")
public class MinioController {@Autowiredprivate MinIoUtil minIoUtil;@Autowiredprivate MinioUtilS minioUtilS;@Value("${minio.endpoint}")private String address;@Value("${minio.bucketName}")private String bucketName;@RequestMapping("/fileInMinio")public R uploadInMinio(MultipartFile file) {List<String> upload = minioUtils.upload(new MultipartFile[]{file});String url = address + "/" + bucketName + "/" + upload.get(0);return R.ok().put("filePath", url);}}
上傳后獲取鏈接為
訪問報錯
解決方式
來到minio控制臺
打開你正在使用的bucket
修改訪問權限為public就行
重新訪問鏈接,應該就能查看
前端代碼
通過父組件導入子組件,注冊子組件,引用子組件彈出
父組件調用方法
// 文件導入importExcel () {this.uploadFileVisible = truethis.$nextTick(() => {this.$refs.uploadFile.init()})}
?子組件vue頁面
包含三種上傳方式的切換
<template><el-dialogtitle="維修處理":close-on-click-modal="true":visible.sync="visible"><el-selectsize="small"v-model="uploadMethodValue"placeholder="請選擇上傳方式"clearable=""filterable><el-optionv-for="d in uploadMethod":key="d.value":label="d.name":value="d.value"></el-option></el-select><el-uploadclass="upload-demo"ref="upload"dragaction="#":on-change="handleChangeSelect":on-exceed="handleExceed":file-list="fileList":limit="1"multiple:auto-upload="false"><i class="el-icon-upload"></i><div class="el-upload__text">將文件拖到此處,或<em>點擊上傳</em></div><divclass="el-upload__tip"slot="tip">只能上傳jpg/png文件,且不超過500kb</div><divclass="el-upload__tip"slot="tip">訪問路徑:{{ filePath }}</div></el-upload></el-dialog>
</template><script>
export default {data () {return {// 對話框顯示狀態visible: false,uploadMethod: [{ name: '本地存儲', value: '1' },{ name: 'oss存儲', value: '2' },{ name: 'miniio', value: '3' }],// 選中的上傳方式uploadMethodValue: '',// 表單數據dataForm: {},filePath: '',fileList: []}},methods: {// 初始化方法init () {this.visible = truethis.filePath = ''},// 文件超出個數提示handleExceed (files, fileList) {this.$message.warning(`當前限制選擇 1 個文件,本次選擇了 ${files.length} 個文件,共選擇了 ${files.length + fileList.length} 個文件`)},handleChangeSelect (file) {if (this.uploadMethodValue === '1') {// 本地存儲this.handleChange(file, '/fileSave/file')} else if (this.uploadMethodValue === '2') {// oss存儲this.handleChange(file, '/fileSave/fileInOSS')} else if (this.uploadMethodValue === '3') {// miniiothis.handleChange(file, '/fileSave/fileInMinio')}},handleChange (file, urlSelect) {let formData = new FormData()formData.append('file', file.raw) // 傳文件this.$http({url: this.$http.adornUrl(urlSelect),method: 'post',data: formData,headers: {'Content-Type': 'multipart/form-data'}}).then(({ data }) => {if (data && data.code === 0) {this.filePath = data.filePaththis.$message({message: '操作成功',type: 'success',duration: 1500})} else {this.$message.error(data.msg)}this.$refs.upload.clearFiles() // 清除文件})}}
}</script>
拓展學習
MultipartFile
?MultipartFile為org.springframework.web.mutipart包下的一個類,也就是說如果想使用MultipartFile這個類就必須引入spring框架,換句話說,如果想在項目中使用MultipartFile這個類,那么項目必須要使用spring框架才可以,否則無法引入這個類。
一般來講使用MultipartFile這個類主要是來實現以表單的形式進行文件上傳功能。
MiltipartFile類注釋說明
?第一句:一種可以接收使用多種請求方式來進行上傳文件的代表形式。也就是說,如果你想用spring框架來實現項目中的文件上傳功能,則MultipartFile可能是最合適的選擇,而這里提到的多種請求方式則可以通俗理解為以表單的形式提交。
? ? ? 第二句:這個文件內容可以存儲到內存中或者存儲在磁盤的臨時位置上。
? ? ? 第三句:無論發生哪種情況,用戶都可以自由地拷貝文件內容到session存儲中,或者以一種永久存儲的形式進行存儲,如果有需要的話。
? ? ? 第四句:這種臨時性的存儲在請求結束之后將會被清除掉。
類中方法
?getName方法
獲取的是前后端約定的傳入文件的參數的名稱,在SpringBoot后臺中則是通過@Param("uploadFile")?注解定義的內容。
getOriginalFileName方法?
getOriginalFileName方法獲取的是文件的完整名稱,包括文件名稱+文件拓展名。
getContentType方法?
getContentType方法獲取的是文件的類型,注意是文件的類型,不是文件的拓展名。
getBytes方法?
getBytes方法用來將文件轉換成一種字節數組的方式進行傳輸,會拋出IOException異常。
getInputStream方法?
getInputStream方法用來將文件轉換成輸入流的形式來傳輸文件,會拋出IOException異常。
transferTo方法?
transferTo方法用來將接收文件傳輸到給定目標路徑,會拋出IOException、IllegalStateException異常。該方法在實際項目開發中使用較少。