<noframes id="bhrfl"><address id="bhrfl"></address>

    <address id="bhrfl"></address>

    <noframes id="bhrfl"><address id="bhrfl"><th id="bhrfl"></th></address>

    <form id="bhrfl"><th id="bhrfl"><progress id="bhrfl"></progress></th></form>

    <em id="bhrfl"><span id="bhrfl"></span></em>

    全部
    常見問題
    產品動態
    精選推薦

    Spring Boot整合Minio實現文件上傳下載功能

    管理 管理 編輯 刪除

    一、Linux 安裝Minio

    安裝

    /root/xxkfz/soft目錄下面創建文件minio文件夾,進入minio文件夾,并創建data目錄;

    [root@xxkfz?soft]#?mkdir?minio
    [root@xxkfz?soft]#?cd?minio
    [root@xxkfz?minio]#?mkdir?data
    

    執行如下命令進行下載

    [root@xxkfz?minio]#?wget?https://dl.min.io/server/minio/release/linux-amd64/minio
    [root@xxkfz?minio]#?chmod?+x?minio??#?賦權
    

    下載完成后如下所示:

    設置賬號密碼

    minio 默認賬號密碼為 minioadmin/minioadmin

    [root@xxkfz?minio]#?export?MINIO_ACCESS_KEY=admin?#?設置控制臺賬號(最少3位)
    [root@xxkfz?minio]#?export?MINIO_SECRET_KEY=12345678?#?設置密碼(最少8位)
    

    直接設置管理員賬號密碼 編輯 /etc/profile 文件即可

    [root@xxkfz?minio]#?vim?/etc/profile
    

    編輯/etc/profile文件,追加如下內容:

    #===============================Minio=============================================
    #?set?minio?environment
    export?MINIO_ROOT_USER=admin
    export?MINIO_ROOT_PASSWORD=admin123
    

    可省略 設置賬號密碼 此步驟!12

    啟動

    進入執行文件目錄/root/xxkfz/soft/minio,自定義端口啟動(默認端口:9000)

    [root@xxkfz?minio]#?nohup?/root/xxkfz/soft/minio/minio?server?--address?:9001?--console-address?:9002?/root/xxkfz/soft/minio/data?>/root/xxkfz/soft/minio/minio.log?2>&1?&
    

    說明:

    • nohup 為后臺啟動
    • ./minio server 啟動命令
    • --address :9001 指定API端口
    • --console-address :9002 指定控制臺端口
    • /usr/local/minio/data 指定存儲目錄
    • >/usr/local/minio/minio.log 2>&1 控制臺日志重定向到/usr/local/minio/minio.log文件中
    • & 后臺運行

    啟動成功:

    啟動成功

    啟動成功

    注意:瀏覽器訪問需要開啟防火墻端口!

    阿里云配置開放9001、9002端口

    測試訪問:http://IP地址:9002

    輸入賬號密碼: admin/12345678 登錄成功!

    設置開機自啟動

    設置Minio服務器宕機后自動重啟

    進入init.d目錄
    [root@xxkfz?minio]#?cd?/etc/rc.d/init.d
    
    新建minio.sh shell腳本文件
    [root@xxkfz?init.d]#?vim?minio.sh?
    
    shell腳本內容
    #!/bin/bash
    #chkconfig:?2345?10?90
    #description:?ping10
    nohup?/root/xxkfz/soft/minio/minio?server?--address?:9001?--console-address?:9002?/root/xxkfz/soft/minio/data?>/root/xxkfz/soft/minio/minio.log?2>&1?&
    
    給shell腳本賦權
    chmod?+x?minio.sh
    
    添加到開機自啟動服務中
    chkconfig?--add?minio.sh
    
    設置開機自啟動
    chkconfig?minio.sh?on
    
    查看是否添加成功
    chkconfig?--list
    

    二、Spring Boot整合Minio

    引入依賴

    pom.xml
    ???
    ????????????org.springframework.boot
    ????????????spring-boot-starter-web
    ????????
    ????????
    ????????????org.projectlombok
    ????????????lombok
    ????????????true
    ????????
    ????????
    ????????????io.minio
    ????????????minio
    ????????????8.2.2
    ????????
    ????????
    ????????????org.apache.commons
    ????????????commons-lang3
    ????????????3.11
    ????????
    

    配置MinIo

    application.yml
    minio:
    ??endpoint:?http://IP地址:9001
    ??accessKey:?admin
    ??secretKey:?12345678
    ??bucketName:?xk-admin
    
    #?配置端口號
    server:
    ??port:?8099
    

    編寫配置類

    MinioConfig.java
    /**
    ?*?@program:?xxkfz-minio
    ?*?@ClassName?MinioConfig.java
    ?*?@author:?公眾號:小小開發者
    ?*?@create:?2024-03-13?10:53
    ?*?@description:?Minio?配置類
    ?**/
    @Data
    @Configuration
    public?class?MinioConfig?{
    
    ????/**
    ?????*?訪問地址
    ?????*/
    ????@Value("${minio.endpoint}")
    ????private?String?endpoint;
    
    ????/**
    ?????*?accessKey類似于用戶ID,用于唯一標識你的賬戶
    ?????*/
    ????@Value("${minio.accessKey}")
    ????private?String?accessKey;
    
    ????/**
    ?????*?secretKey是你賬戶的密碼
    ?????*/
    ????@Value("${minio.secretKey}")
    ????private?String?secretKey;
    
    ????/**
    ?????*?默認存儲桶
    ?????*/
    ????@Value("${minio.bucketName}")
    ????private?String?bucketName;
    
    ????@Bean
    ????public?MinioClient?minioClient()?{
    ????????MinioClient?minioClient?=?MinioClient.builder().endpoint(endpoint).credentials(accessKey,?secretKey).build();
    ????????return?minioClient;
    ????}
    }
    

    編寫Minio操作工具類

    MinioUtils.java
    /**
    ?*?@program:?xxkfz-minio
    ?*?@ClassName?MinioUtils.java
    ?*?@author:?公眾號:小小開發者
    ?*?@create:?2024-03-13?10:55
    ?*?@description:?MinIO操作工具類
    ?**/
    @Slf4j
    @Component
    public?class?MinioUtils?{
    
    ????@Autowired
    ????private?MinioClient?minioClient;
    
    
    ????/**
    ?????*?啟動SpringBoot容器的時候初始化Bucket
    ?????*?如果沒有Bucket則創建
    ?????*
    ?????*?@param?bucketName
    ?????*/
    ????public?void?createBucket(String?bucketName)?{
    ????????try?{
    ????????????if?(!bucketExists(bucketName))?{
    ????????????????minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
    ????????????????log.info("創建bucketName?=?{}完成!",?bucketName);
    ????????????????return;
    ????????????}
    ????????????log.info("bucketName?=?{}已存在!策略為:{}",?bucketName,?getBucketPolicy(bucketName));
    ????????}?catch?(Exception?e)?{
    ????????????log.error("創建bucketName?=?{}異常!e?=?{}",?bucketName,?e);
    ????????}
    ????}
    
    ????/**
    ?????*?判斷Bucket是否存在,true:存在,false:不存在
    ?????*
    ?????*?@param?bucketName
    ?????*?@return
    ?????*/
    ????@SneakyThrows
    ????public?boolean?bucketExists(String?bucketName)?{
    ????????return?minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
    ????}
    
    ????/**
    ?????*?獲得Bucket的策略
    ?????*
    ?????*?@param?bucketName
    ?????*?@return
    ?????*/
    ????@SneakyThrows
    ????public?String?getBucketPolicy(String?bucketName)?{
    ????????return?minioClient.getBucketPolicy(GetBucketPolicyArgs.builder().bucket(bucketName).build());
    ????}
    
    ????/**
    ?????*?獲得所有Bucket列表
    ?????*
    ?????*?@return
    ?????*/
    ????@SneakyThrows
    ????public?List?getAllBuckets()?{
    ????????return?minioClient.listBuckets();
    ????}
    
    ????/**
    ?????*?根據bucketName獲取其相關信息
    ?????*
    ?????*?@param?bucketName
    ?????*?@return
    ?????*/
    ????@SneakyThrows(Exception.class)
    ????public?Optional?getBucket(String?bucketName)?{
    ????????return?getAllBuckets().stream().filter(b?->?b.name().equals(bucketName)).findFirst();
    ????}
    
    ????/**
    ?????*?根據bucketName刪除Bucket,true:刪除成功;?false:刪除失敗,文件或已不存在
    ?????*
    ?????*?@param?bucketName
    ?????*?@throws?Exception
    ?????*/
    ????@SneakyThrows(Exception.class)
    ????public?void?removeBucket(String?bucketName)?{
    ????????minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
    ????}
    
    
    ????/**
    ?????*?判斷文件是否存在
    ?????*
    ?????*?@param?bucketName
    ?????*?@param?objectName
    ?????*?@return
    ?????*/
    ????public?boolean?isObjectExist(String?bucketName,?String?objectName)?{
    ????????boolean?exist?=?true;
    ????????try?{
    ????????????minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build());
    ????????}?catch?(Exception?e)?{
    ????????????log.error("[Minio工具類]>>>>?判斷文件是否存在,?異常:",?e);
    ????????????exist?=?false;
    ????????}
    ????????return?exist;
    ????}
    
    ????/**
    ?????*?判斷文件夾是否存在
    ?????*
    ?????*?@param?bucketName
    ?????*?@param?objectName
    ?????*?@return
    ?????*/
    ????public?boolean?isFolderExist(String?bucketName,?String?objectName)?{
    ????????boolean?exist?=?false;
    ????????try?{
    ????????????Iterable>?results?=?minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).prefix(objectName).recursive(false).build());
    ????????????for?(Result?result?:?results)?{
    ????????????????Item?item?=?result.get();
    ????????????????if?(item.isDir()?&&?objectName.equals(item.objectName()))?{
    ????????????????????exist?=?true;
    ????????????????}
    ????????????}
    ????????}?catch?(Exception?e)?{
    ????????????log.error("[Minio工具類]>>>>?判斷文件夾是否存在,異常:",?e);
    ????????????exist?=?false;
    ????????}
    ????????return?exist;
    ????}
    
    ????/**
    ?????*?根據文件前置查詢文件
    ?????*
    ?????*?@param?bucketName?存儲桶
    ?????*?@param?prefix?????前綴
    ?????*?@param?recursive??是否使用遞歸查詢
    ?????*?@return?MinioItem?列表
    ?????*/
    ????@SneakyThrows(Exception.class)
    ????public?List?getAllObjectsByPrefix(String?bucketName,?String?prefix,?boolean?recursive)?{
    ????????List?list?=?new?ArrayList<>();
    ????????Iterable>?objectsIterator?=?minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build());
    ????????if?(objectsIterator?!=?null)?{
    ????????????for?(Result?o?:?objectsIterator)?{
    ????????????????Item?item?=?o.get();
    ????????????????list.add(item);
    ????????????}
    ????????}
    ????????return?list;
    ????}
    
    ????/**
    ?????*?獲取文件流
    ?????*
    ?????*?@param?bucketName?存儲桶
    ?????*?@param?objectName?文件名
    ?????*?@return?二進制流
    ?????*/
    ????@SneakyThrows(Exception.class)
    ????public?InputStream?getObject(String?bucketName,?String?objectName)?{
    ????????return?minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build());
    ????}
    
    ????/**
    ?????*?斷點下載
    ?????*
    ?????*?@param?bucketName?存儲桶
    ?????*?@param?objectName?文件名稱
    ?????*?@param?offset?????起始字節的位置
    ?????*?@param?length?????要讀取的長度
    ?????*?@return?二進制流
    ?????*/
    ????@SneakyThrows(Exception.class)
    ????public?InputStream?getObject(String?bucketName,?String?objectName,?long?offset,?long?length)?{
    ????????return?minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).offset(offset).length(length).build());
    ????}
    
    ????/**
    ?????*?獲取路徑下文件列表
    ?????*
    ?????*?@param?bucketName?存儲桶
    ?????*?@param?prefix?????文件名稱
    ?????*?@param?recursive??是否遞歸查找,false:模擬文件夾結構查找
    ?????*?@return?二進制流
    ?????*/
    ????public?Iterable>?listObjects(String?bucketName,?String?prefix,?boolean?recursive)?{
    ????????return?minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build());
    ????}
    
    ????/**
    ?????*?使用MultipartFile進行文件上傳
    ?????*
    ?????*?@param?bucketName??存儲桶
    ?????*?@param?file????????文件名
    ?????*?@param?objectName??對象名
    ?????*?@param?contentType?類型
    ?????*?@return
    ?????*/
    ????@SneakyThrows(Exception.class)
    ????public?ObjectWriteResponse?uploadFile(String?bucketName,?MultipartFile?file,?String?objectName,?String?contentType)?{
    ????????InputStream?inputStream?=?file.getInputStream();
    ????????return?minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).contentType(contentType).stream(inputStream,?inputStream.available(),?-1).build());
    ????}
    
    ????/**
    ?????*?圖片上傳
    ?????*
    ?????*?@param?bucketName
    ?????*?@param?imageBase64
    ?????*?@param?imageName
    ?????*?@return
    ?????*/
    ????public?ObjectWriteResponse?uploadImage(String?bucketName,?String?imageBase64,?String?imageName)?{
    ????????if?(!StringUtils.isEmpty(imageBase64))?{
    ????????????InputStream?in?=?base64ToInputStream(imageBase64);
    ????????????String?newName?=?System.currentTimeMillis()?+?"_"?+?imageName?+?".jpg";
    ????????????String?year?=?String.valueOf(new?Date().getYear());
    ????????????String?month?=?String.valueOf(new?Date().getMonth());
    ????????????return?uploadFile(bucketName,?year?+?"/"?+?month?+?"/"?+?newName,?in);
    
    ????????}
    ????????return?null;
    ????}
    
    ????public?static?InputStream?base64ToInputStream(String?base64)?{
    ????????ByteArrayInputStream?stream?=?null;
    ????????try?{
    ????????????byte[]?bytes?=?Base64.getEncoder().encode(base64.trim().getBytes());
    ????????????stream?=?new?ByteArrayInputStream(bytes);
    ????????}?catch?(Exception?e)?{
    ????????????e.printStackTrace();
    ????????}
    ????????return?stream;
    ????}
    
    
    ????/**
    ?????*?上傳本地文件
    ?????*
    ?????*?@param?bucketName?存儲桶
    ?????*?@param?objectName?對象名稱
    ?????*?@param?fileName???本地文件路徑
    ?????*?@return
    ?????*/
    ????@SneakyThrows(Exception.class)
    ????public?ObjectWriteResponse?uploadFile(String?bucketName,?String?objectName,?String?fileName)?{
    ????????return?minioClient.uploadObject(UploadObjectArgs.builder().bucket(bucketName).object(objectName).filename(fileName).build());
    ????}
    
    ????/**
    ?????*?通過流上傳文件
    ?????*
    ?????*?@param?bucketName??存儲桶
    ?????*?@param?objectName??文件對象
    ?????*?@param?inputStream?文件流
    ?????*?@return
    ?????*/
    ????@SneakyThrows(Exception.class)
    ????public?ObjectWriteResponse?uploadFile(String?bucketName,?String?objectName,?InputStream?inputStream)?{
    ????????return?minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(inputStream,?inputStream.available(),?-1).build());
    ????}
    
    ????/**
    ?????*?創建文件夾或目錄
    ?????*
    ?????*?@param?bucketName?存儲桶
    ?????*?@param?objectName?目錄路徑
    ?????*?@return
    ?????*/
    ????@SneakyThrows(Exception.class)
    ????public?ObjectWriteResponse?createDir(String?bucketName,?String?objectName)?{
    ????????return?minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(new?ByteArrayInputStream(new?byte[]{}),?0,?-1).build());
    ????}
    
    ????/**
    ?????*?獲取文件信息,?如果拋出異常則說明文件不存在
    ?????*
    ?????*?@param?bucketName?存儲桶
    ?????*?@param?objectName?文件名稱
    ?????*?@return
    ?????*/
    ????@SneakyThrows(Exception.class)
    ????public?String?getFileStatusInfo(String?bucketName,?String?objectName)?{
    ????????return?minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build()).toString();
    ????}
    
    ????/**
    ?????*?拷貝文件
    ?????*
    ?????*?@param?bucketName????存儲桶
    ?????*?@param?objectName????文件名
    ?????*?@param?srcBucketName?目標存儲桶
    ?????*?@param?srcObjectName?目標文件名
    ?????*/
    ????@SneakyThrows(Exception.class)
    ????public?ObjectWriteResponse?copyFile(String?bucketName,?String?objectName,?String?srcBucketName,?String?srcObjectName)?{
    ????????return?minioClient.copyObject(CopyObjectArgs.builder().source(CopySource.builder().bucket(bucketName).object(objectName).build()).bucket(srcBucketName).object(srcObjectName).build());
    ????}
    
    ????/**
    ?????*?刪除文件
    ?????*
    ?????*?@param?bucketName?存儲桶
    ?????*?@param?objectName?文件名稱
    ?????*/
    ????@SneakyThrows(Exception.class)
    ????public?void?removeFile(String?bucketName,?String?objectName)?{
    ????????minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build());
    ????}
    
    ????/**
    ?????*?批量刪除文件
    ?????*
    ?????*?@param?bucketName?存儲桶
    ?????*?@param?keys???????需要刪除的文件列表
    ?????*?@return
    ?????*/
    ????public?void?removeFiles(String?bucketName,?List?keys)?{
    ????????List?objects?=?new?LinkedList<>();
    ????????keys.forEach(s?->?{
    ????????????objects.add(new?DeleteObject(s));
    ????????????try?{
    ????????????????removeFile(bucketName,?s);
    ????????????}?catch?(Exception?e)?{
    ????????????????log.error("[Minio工具類]>>>>?批量刪除文件,異常:",?e);
    ????????????}
    ????????});
    ????}
    
    ????/**
    ?????*?獲取文件外鏈
    ?????*
    ?????*?@param?bucketName?存儲桶
    ?????*?@param?objectName?文件名
    ?????*?@param?expires????過期時間?<=7?秒?(外鏈有效時間(單位:秒))
    ?????*?@return?url
    ?????*/
    ????@SneakyThrows(Exception.class)
    ????public?String?getPresignedObjectUrl(String?bucketName,?String?objectName,?Integer?expires)?{
    ????????GetPresignedObjectUrlArgs?args?=?GetPresignedObjectUrlArgs.builder().expiry(expires).bucket(bucketName).object(objectName).build();
    ????????return?minioClient.getPresignedObjectUrl(args);
    ????}
    
    ????/**
    ?????*?獲得文件外鏈
    ?????*
    ?????*?@param?bucketName
    ?????*?@param?objectName
    ?????*?@return?url
    ?????*/
    ????@SneakyThrows(Exception.class)
    ????public?String?getPresignedObjectUrl(String?bucketName,?String?objectName)?{
    ????????GetPresignedObjectUrlArgs?args?=?GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(objectName).method(Method.GET).build();
    ????????return?minioClient.getPresignedObjectUrl(args);
    ????}
    
    ????/**
    ?????*?將URLDecoder編碼轉成UTF8
    ?????*
    ?????*?@param?str
    ?????*?@return
    ?????*?@throws?UnsupportedEncodingException
    ?????*/
    ????public?String?getUtf8ByURLDecoder(String?str)?throws?UnsupportedEncodingException?{
    ????????String?url?=?str.replaceAll("%(?![0-9a-fA-F]{2})",?"%25");
    ????????return?URLDecoder.decode(url,?"UTF-8");
    ????}
    }
    

    項目啟動初始化配置

    創建配置類InitConfig.java,并實現了InitializingBean接口重寫afterPropertiesSet方法。

    該方法主要實現邏輯:在項目啟動的時候初始化Bucket,如果沒有則進行創建!

    InitConfig.java
    /**
    ?*?@program:?xxkfz-minio
    ?*?@ClassName?Init.java
    ?*?@author:?wust
    ?*?@create:?2024-03-16?10:34
    ?*?@description:?項目啟動初始化配置
    ?**/
    @Component
    @Slf4j
    ????public?class?InitConfig?implements?InitializingBean?{
    
    ????@Autowired
    ????private?MinioUtils?minioUtils;
    
    
    ????@Autowired
    ????private?MinioConfig?minioConfig;
    
    ????@Override
    ????public?void?afterPropertiesSet()?throws?Exception?{
    ????????//?項目啟動創建Bucket,不存在則進行創建
    ????????minioUtils.createBucket(minioConfig.getBucketName());
    ????}
    }
    

    編寫測試接口

    MinioController.java
    /**
    ?*?@program:?xxkfz-minio
    ?*?@ClassName?OSSController.java
    ?*?@author:?wust
    ?*?@create:?2024-03-13?11:01
    ?*?@description:
    ?**/
    @Slf4j
    @RestController
    @RequestMapping("/oss")
    public?class?MinioController?{
    
    ????@Autowired
    ????private?MinioUtils?minioUtils;
    
    ????@Autowired
    ????private?MinioConfig?minioConfig;
    
    ????/**
    ?????*?文件上傳
    ?????*
    ?????*?@param?file
    ?????*/
    ????@PostMapping("/upload")
    ????public?String?upload(@RequestParam("file")?MultipartFile?file)?{
    ????????try?{
    ????????????//文件名
    ????????????String?fileName?=?file.getOriginalFilename();
    ????????????String?newFileName?=?System.currentTimeMillis()?+?"."?+?StringUtils.substringAfterLast(fileName,?".");
    ????????????//類型
    ????????????String?contentType?=?file.getContentType();
    ????????????minioUtils.uploadFile(minioConfig.getBucketName(),?file,?newFileName,?contentType);
    ????????????return?"上傳成功,文件名:"?+?newFileName;
    ????????}?catch?(Exception?e)?{
    ????????????e.printStackTrace();
    ????????????return?"上傳失敗";
    ????????}
    ????}
    
    ????/**
    ?????*?刪除
    ?????*
    ?????*?@param?fileName
    ?????*/
    ????@DeleteMapping("/")
    ????public?void?delete(@RequestParam("fileName")?String?fileName)?{
    ????????minioUtils.removeFile(minioConfig.getBucketName(),?fileName);
    ????}
    
    ????/**
    ?????*?獲取文件信息
    ?????*
    ?????*?@param?fileName
    ?????*?@return
    ?????*/
    ????@GetMapping("/info")
    ????public?String?getFileStatusInfo(@RequestParam("fileName")?String?fileName)?{
    ????????return?minioUtils.getFileStatusInfo(minioConfig.getBucketName(),?fileName);
    ????}
    
    ????/**
    ?????*?獲取文件外鏈
    ?????*
    ?????*?@param?fileName
    ?????*?@return
    ?????*/
    ????@GetMapping("/url")
    ????public?String?getPresignedObjectUrl(@RequestParam("fileName")?String?fileName)?{
    ????????return?minioUtils.getPresignedObjectUrl(minioConfig.getBucketName(),?fileName);
    ????}
    
    ????/**
    ?????*?文件下載
    ?????*
    ?????*?@param?fileName
    ?????*?@param?response
    ?????*/
    ????@GetMapping("/download")
    ????public?void?download(@RequestParam("fileName")?String?fileName,?HttpServletResponse?response)?{
    ????????try?{
    ????????????InputStream?fileInputStream?=?minioUtils.getObject(minioConfig.getBucketName(),?fileName);
    ????????????response.setHeader("Content-Disposition",?"attachment;filename="?+?fileName);
    ????????????response.setContentType("application/force-download");
    ????????????response.setCharacterEncoding("UTF-8");
    ????????????IOUtils.copy(fileInputStream,?response.getOutputStream());
    ????????}?catch?(Exception?e)?{
    ????????????log.error("下載失敗");
    ????????}
    ????}
    }
    

    測試驗證

    啟動項目:

    上傳圖片

    測試接口:http://localhost:8099/oss/upload

    進入服務器查看文件上傳情況。

    進入目錄:/root/xxkfz/soft/minio/data/xk-admin

    當然,也可以直接訪問minio的地址:http://IP地址:9001/xk-admin/1710558001536.jpg。驗證文件是否上傳成功。

    獲取文件信息

    測試接口:http://localhost:8099/oss/info

    獲取文件外鏈

    測試接口:http://localhost:8099/oss/url

    下載文件

    測試接口:http://localhost:8099/oss/download


    請登錄后查看

    小碼二開 最后編輯于2024-05-16 15:56:42

    快捷回復
    回復
    回復
    回復({{post_count}}) {{!is_user ? '我的回復' :'全部回復'}}
    排序 默認正序 回復倒序 點贊倒序

    {{item.user_info.nickname ? item.user_info.nickname : item.user_name}} LV.{{ item.user_info.bbs_level }}

    作者 管理員 企業

    {{item.floor}}# 同步到gitee 已同步到gitee {{item.is_suggest == 1? '取消推薦': '推薦'}}
    {{item.is_suggest == 1? '取消推薦': '推薦'}}
    沙發 板凳 地板 {{item.floor}}#
    {{item.user_info.title || '暫無簡介'}}
    附件

    {{itemf.name}}

    {{item.created_at}}  {{item.ip_address}}
    打賞
    已打賞¥{{item.reward_price}}
    {{item.like_count}}
    {{item.showReply ? '取消回復' : '回復'}}
    刪除
    回復
    回復

    {{itemc.user_info.nickname}}

    {{itemc.user_name}}

    回復 {{itemc.comment_user_info.nickname}}

    附件

    {{itemf.name}}

    {{itemc.created_at}}
    打賞
    已打賞¥{{itemc.reward_price}}
    {{itemc.like_count}}
    {{itemc.showReply ? '取消回復' : '回復'}}
    刪除
    回復
    回復
    查看更多
    打賞
    已打賞¥{{reward_price}}
    6902
    {{like_count}}
    {{collect_count}}
    添加回復 ({{post_count}})

    相關推薦

    快速安全登錄

    使用微信掃碼登錄
    {{item.label}} 加精
    {{item.label}} {{item.label}} 板塊推薦 常見問題 產品動態 精選推薦 首頁頭條 首頁動態 首頁推薦
    取 消 確 定
    回復
    回復
    問題:
    問題自動獲取的帖子內容,不準確時需要手動修改. [獲取答案]
    答案:
    提交
    bug 需求 取 消 確 定
    打賞金額
    當前余額:¥{{rewardUserInfo.reward_price}}
    {{item.price}}元
    請輸入 0.1-{{reward_max_price}} 范圍內的數值
    打賞成功
    ¥{{price}}
    完成 確認打賞

    微信登錄/注冊

    切換手機號登錄

    {{ bind_phone ? '綁定手機' : '手機登錄'}}

    {{codeText}}
    切換微信登錄/注冊
    暫不綁定
    亚洲欧美字幕
    CRMEB客服

    CRMEB咨詢熱線 咨詢熱線

    400-8888-794

    微信掃碼咨詢

    CRMEB開源商城下載 源碼下載 CRMEB幫助文檔 幫助文檔
    返回頂部 返回頂部
    CRMEB客服