如何在springboot项目中使用minio上传下载删除文件

引入maven依赖

<!--  minio   -->
<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.2.2</version>
</dependency>

申请 bucket | access_key | secret_key

项目中配置相关参数

    minio:# access_keyaccessKey: xxxxxx# secret_keysecretKey: xxxxxx# bucketbucketName: bucket1# 内网地址endpoint: http://127.0.0.1:9000# 外网地址website: https://xxx.xxx.cn:9000# 自定义文件大小限制 注:要与spring.servlet.multipart.max-file-size | max-request-size 区分开maxFileSize:img: 10video: 30

endpoint | website | maxFileSize 可根据项目需要增删,后面不再赘述。

Minio 配置信息


/*** Minio 配置信息** @author ruoyi*/
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioConfig
{/*** 用户名*/private String accessKey;/*** 密码*/private String secretKey;/*** 存储桶名称*/private String bucketName;/*** 服务地址*/private String endpoint;/*** 公网*/private String webSite;/*** 文件大小限制*/private MediaMaxFileSize maxFileSize;public static class MediaMaxFileSize{private Long img;private Long video;public Long getImg() {return img;}public void setImg(Long img) {this.img = img;}public Long getVideo() {return video;}public void setVideo(Long video) {this.video = video;}}public String getWebSite() {return webSite;}public void setWebSite(String webSite) {this.webSite = webSite;}public MediaMaxFileSize getMaxFileSize() {return maxFileSize;}public void setMaxFileSize(MediaMaxFileSize maxFileSize) {this.maxFileSize = maxFileSize;}public String getAccessKey() {return accessKey;}public void setAccessKey(String accessKey) {this.accessKey = accessKey;}public String getSecretKey() {return secretKey;}public void setSecretKey(String secretKey) {this.secretKey = secretKey;}public String getBucketName() {return bucketName;}public void setBucketName(String bucketName) {this.bucketName = bucketName;}public String getEndpoint() {return endpoint;}public void setEndpoint(String endpoint) {this.endpoint = endpoint;}@Beanpublic MinioClient getMinioClient() {return MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();}
}

/*** 文件对象实体类*/
public class MinioFile implements Serializable {// 文件服务器文件所属组private String bucketName;// 不带文件组的文件URLprivate String path;// 带文件组的文件URLprivate String fullPath;// 站点信息private String webSite;// 带站点的文件URLprivate String webUrl;// 原始文件名private String fileName;// 内网廉价而private String intranetWebSite;// 内网地址private String intranetWebUrl;// 其他参数private Map<String, Object> params = new HashMap<>();public String getFullPath() {return fullPath;}public void setFullPath(String fullPath) {this.fullPath = fullPath;}public String getPath() {return path;}public void setPath(String path) {this.path = path;}public String getWebSite() {return webSite;}public void setWebSite(String webSite) {this.webSite = webSite;}public String getWebUrl() {return webUrl;}public void setWebUrl(String webUrl) {this.webUrl = webUrl;}public String getFileName() {return fileName;}public void setFileName(String fileName) {this.fileName = fileName;}public String getIntranetWebUrl() {return intranetWebUrl;}public void setIntranetWebUrl(String intranetWebUrl) {this.intranetWebUrl = intranetWebUrl;}public String getIntranetWebSite() {return intranetWebSite;}public void setIntranetWebSite(String intranetWebSite) {this.intranetWebSite = intranetWebSite;}public String getBucketName() {return bucketName;}public void setBucketName(String bucketName) {this.bucketName = bucketName;}public Map<String, Object> getParams() {if (params == null) {params = new HashMap<>();}return params;}public void setParams(Map<String, Object> params) {this.params = params;}public Object getParam(String key) {if (params == null) {params = new HashMap<>();return null;}return params.get(key);}public void putParam(String key, Object value) {if (params == null) {params = new HashMap<>();}params.put(key, value);}}

文件上传下载删除工具类封装

项目基于RuoYi开源框架搭建,因此此处工具类引入开源框架中一些内置工具类


import com.ruoyi.common.exception.file.InvalidExtensionException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.MimeTypeUtils;
import com.ruoyi.common.utils.uuid.Seq;
import io.minio.GetPresignedObjectUrlArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import io.minio.http.Method;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.io.InputStream;
import java.util.Date;/*** Minio 文件存储工具类* * @author ruoyi*/
@Component
public class MinioUtil
{private static Logger log = LoggerFactory.getLogger(MinioUtil.class);/*** minio实例*/private static MinioClient minioClient;/*** minio配置类*/private static MinioConfig minioConfig;@Autowiredpublic void setMinioUtil(MinioClient minioClient, MinioConfig minioConfig){MinioUtil.minioClient = minioClient;MinioUtil.minioConfig = minioConfig;}public MinioFile uploadFile(MultipartFile file, String fileType, String filePurpose) throws InvalidExtensionException, IOException {if("01".equals(fileType)){FileUploadUtils.assertAllowed(file, MimeTypeUtils.IMAGE_EXTENSION_10001, minioConfig.getMaxFileSize().getImg() * 1024 * 1024);} else if ("02".equals(fileType)) {FileUploadUtils.assertAllowed(file, MimeTypeUtils.VIDEO_EXTENSION_10002, minioConfig.getMaxFileSize().getVideo() * 1024 * 1024);}// 年月String yyyyMM = DateUtils.parseDateToStr("yyyyMM", new Date());// 文件名 moduleName/业务类型/文件类型/年月/Seq随机字符/文件后缀String fileName = StringUtils.format("{}/{}/{}/{}/{}.{}","moduleName", getFilePurpose(filePurpose)// 使用用途, getFileType(fileType)//文件类型, yyyyMM, Seq.getId(), FileUploadUtils.getExtension(file));return uploadFile(file, fileName);}private MinioFile uploadFile(MultipartFile file, String fileName) throws IOException {String webUrl = uploadFile(minioConfig.getBucketName(), fileName, file);MinioFile minioFile = new MinioFile();minioFile.setBucketName(minioConfig.getBucketName());minioFile.setPath(fileName);minioFile.setFullPath(StringUtils.format("{}/{}",minioConfig.getBucketName(),fileName));minioFile.setWebSite(minioConfig.getWebSite());minioFile.setWebUrl(webUrl.replace(minioConfig.getEndpoint(),minioConfig.getWebSite()));minioFile.setFileName(file.getOriginalFilename());minioFile.setIntranetWebSite(minioConfig.getEndpoint());minioFile.setIntranetWebUrl(webUrl);return minioFile;}/*** 上传文件* * @param bucketName 桶名称* @param fileName* @throws IOException*/private String uploadFile(String bucketName, String fileName, MultipartFile multipartFile) throws IOException{String url = "";try (InputStream inputStream = multipartFile.getInputStream()){minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(fileName).stream(inputStream, multipartFile.getSize(), -1).contentType(multipartFile.getContentType()).build());url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(fileName).method(Method.GET).build());url = url.substring(0, url.indexOf('?'));return ServletUtils.urlDecode(url);}catch (Exception e){throw new IOException(e.getMessage(), e);}}/*** 删除文件* @param fileName*/public void removeFile(String fileName){try{minioClient.removeObject(RemoveObjectArgs.builder().bucket(minioConfig.getBucketName()).object(fileName).build());}catch (Exception e){e.printStackTrace();log.error("MinioUtil-uploadMinio-error", e);}}/*** 文件类型 可自定义* @param fileType* @return*/private String getFileType(String fileType){String fileTypeName = null;switch (fileType){case "01":fileTypeName = "image";break;case "02":fileTypeName = "video";break;default:fileTypeName = "undefined";}return fileTypeName;}/*** 获取文件使用用途 可自定义* @param filePurpose* @return*/private String getFilePurpose(String filePurpose){String filePurposeType = null;switch (filePurpose){case "01":filePurposeType = "banner";break;default:filePurposeType = "undefined";}return filePurposeType;}}

MimeTypeUtils.IMAGE_EXTENSION_10001 和 MimeTypeUtils.VIDEO_EXTENSION_10002为在原框架工具类上新增自定义文件后缀
另根据业务需要,对框架FileUploadUtils中的assertAllowed进行方法重载

/*** 文件大小校验** @param file 上传的文件* @return* @throws FileSizeLimitExceededException 如果超出最大大小* @throws InvalidExtensionException*/public static final void assertAllowed(MultipartFile file, String[] allowedExtension)throws FileSizeLimitExceededException, InvalidExtensionException{assertAllowed(file, allowedExtension, DEFAULT_MAX_SIZE);}/*** 文件大小校验** @param file 上传的文件* @param maxSize 最大限制* @return* @throws FileSizeLimitExceededException 如果超出最大大小* @throws InvalidExtensionException*/public static final void assertAllowed(MultipartFile file, String[] allowedExtension, long maxSize)throws FileSizeLimitExceededException, InvalidExtensionException{long size = file.getSize();if (size > maxSize){throw new FileSizeLimitExceededException(maxSize / 1024 / 1024);}String fileName = file.getOriginalFilename();String extension = getExtension(file);if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension)){if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION){throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension,fileName);}else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION){throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension,fileName);}else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION){throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension,fileName);}else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION){throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension,fileName);}else if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION_10001){throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension,fileName);}else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION_10002){throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension,fileName);}else{throw new InvalidExtensionException(allowedExtension, extension, fileName);}}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/166805.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ROLLUP 的几点说明(十七)

ROLLUP 最根本的作用是提高某些查询的查询效率&#xff08;无论是通过聚合来减少数据量&#xff0c;还是修改列顺序以匹配前缀索引&#xff09;。因此 ROLLUP 的含义已经超出了“上卷”的范围。这也是为什么在源代码中&#xff0c;将其命名为 Materialized Index&#xff08;物…

土壤教学经典用图30张

一、土壤分布 二、土壤形成与气候 三、土壤形成与地形 四、土壤形成与成土母质 五、成土过程示意图 六、土壤剖面实景图 七、土壤剖面示意图 八、土壤质地 以上图片多来源于 人教、湘教、鲁教、中图、沪教 五套新教材及地图册

忘记7-zip密码,如何解压文件?

7z压缩包设置了密码&#xff0c;解压的时候就需要输入正确对密码才能顺利解压出文件&#xff0c;正常当我们解压文件或者删除密码的时候&#xff0c;虽然方法多&#xff0c;但是都需要输入正确的密码才能完成。忘记密码就无法进行操作。 那么&#xff0c;忘记了7z压缩包的密码…

华为云测试计划CodeArts TestPlan常见问答汇总

1.【TestPlan】测试用例界面操作历史&#xff0c;能记录哪些操作 答&#xff1a;除了附件上传、更新、用例评论没有记录的&#xff0c;其他测试用例详情内的所有内容&#xff0c;比如描述、条件、测试步骤修改都有记录&#xff1b; 2.【TestPlan】测试用例等级选择规则是什么&…

YOLOv3老矣尚能战否?基于YOLOv3开发构建建钢铁产业产品智能自动化检测识别系统,我们来与YOLOv5进行全方位对比评测

钢铁产业产品智能自动化检测识别相关的项目在我们前面的博文中已经有了相应的实践了&#xff0c;感兴趣的话可以自行移步阅读即可&#xff1a;《python基于DETR(DEtection TRansformer)开发构建钢铁产业产品智能自动化检测识别系统》 《AI助力钢铁产业数字化&#xff0c;pytho…

计算两个经纬度之间的真是距离----c++

来源:https://www.open-open.com/lib/view/open1430573897802.html #include <cmath> #define EARTH_RADIUS 6371.0;// 地球半径&#xff0c;单位千米static double HaverSin(double theta) {double v sin(theta / 2);return v * v; }static double ConvertDegreesToR…

OPPO VOOC快充原理

1 USB 3.0标准A插头 USB 3.0连接器是基于USB 2.0改进而来的&#xff0c;这个设计给USB 3.0连接器带来了一些潜在风险&#xff0c;如果USB 3.0设备插入主机的速度太慢&#xff0c;3.0的针脚还没来得及被识别到&#xff0c;就会被主机判定成USB 2.0的设备。 Figure 1-1 USB 3.0标…

centos系统下,docker安装sqlserver并用本地Navicat连接

文章目录 一&#xff0c;centos下安装docker二&#xff0c;docker安装sqlserver20192.1 安装遇到的问题2.1.1 修改用户名进不去数据库2.1.2 安装2022版的sqlserver发现启动失败 三&#xff0c;Navicat连接centos下的sqlserver3.1 下载ODBC Driver 参考微软网址&#xff1a; 使…

代码随想录算法训练营第四十五天【动态规划part07】 | 70. 爬楼梯 (进阶)、322. 零钱兑换、279.完全平方数

70. 爬楼梯 &#xff08;进阶&#xff09; 题目链接&#xff1a; 题目页面 求解思路&#xff1a; 动规五部曲 确定dp数组及其下标含义&#xff1a;爬到有i阶楼梯的楼顶&#xff0c;有dp[i]种方法递推公式&#xff1a;dp[i] dp[i-j];dp数组的初始化&#xff1a;dp[0] 1;确…

EcuM介绍

ECUM 1. ECUM 主要需求2. EcuM 设计详情2.1 启动与下电休眠2.1.1 启动与初始化2.1.2 EcuM 下电/休眠2.2 唤醒事件管理2.3 ECUM 模式2.3.1 Flexible2.3.2 Fixed2.3.3 Startup2.3.4 Shutdown2.3.5 SLEEP PHASE: Poll or Halt3. EcuM 集成接口调用4. 名称缩写解释5. 参考文档1. EC…

数据治理技术之数据清洗

数据清洗背景 数据质量一般由准确性、完整性、一致性、时效性、可信性以及可解释性等特征来描述&#xff0c;根据 Rahm 等人在 2000 年对数据质量基于单数据源还是多数据源以及问题出在模式层还是实例层的标准进行分类&#xff0c;将数据质量问题分为单数据源模式层问题、单数…

虚幻学习笔记—给UI添加动画

一、前言 本文所使用的虚幻版本为5.3.2&#xff0c;之前工作都是用unity&#xff0c;做这类效果用的最多的是一个DoTween的插件&#xff0c;在虚幻中都内置集成了这这种效果制作。 图1.1 UI动画 二、过程 1、首先&#xff0c;在诸如按钮、图像等可交互控件中选中&#xff0c;如…

centos userad命令详解

命令作用 用于创建用户常见参数 -d 指定用户的家目录-e 账号的到期时间&#xff0c;格式YYYY-MM-DD-u 指定该用户的默认UID&#xff0c;&#xff08;centos7开始1000是普通用户的第一个UID&#xff09;-g 指定一个初始的用户基本组&#xff08;必须已经存在&#xff09;-G 指定…

计算机网络之运输层

一、概述 物理层、数据链路层以及网络层它们共同解决了将主机通过异构网络互联起来所面临的的问题&#xff0c;实现了主机到主机的通信 但实际上在计算机网络中进行通信的真正实体是位于通信两端主机中的进程 如何为运行在不同主机上的应用进程提供直接的通信服务时运输层的任务…

基于Boost.Asio实现端口映射器

Boost.Asio 是一个功能强大的 C 库&#xff0c;用于异步编程和网络编程&#xff0c;它提供了跨平台的异步 I/O 操作。在这篇文章中&#xff0c;我们将深入分析一个使用 Boost.Asio 实现的简单端口映射服务器&#xff0c;该服务器能够将本地端口的数据包转发到指定的远程服务器上…

从设计上理解JDK动态代理

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 照理说&#xff0c;动态…

上门预约小程序开发优势

想要放松身心&#xff0c;享受按摩的舒适感&#xff1f;那就需要一个专业的按摩师来上门服务。我们开发的预约按摩小程序app系统&#xff0c;汇聚各类上门按摩服务&#xff0c;包括推拿SPA、小儿推拿、中医等&#xff0c;为您提供高价值、高标准的养生健康体验。24小时随时提供…

GEE土地分类——使用随机森林方法和多源遥感数据进行面向对象的土地分类NAIP数据为例

简介: 数据: 国家农业图像计划 (NAIP) 在美国大陆的农业生长季节获取航空图像。 NAIP 项目每年根据可用资金和图像获取周期签订合同。从 2003 年开始,NAIP 以 5 年为一个周期。2008 年是过渡年,2009 年开始采用 3 年周期。 NAIP 图像以一米的地面采样距离 (GSD) 采集,水…

【前端】让列表像Excel单元格一样编辑

前言 领导说了一堆的话,最后总结一句就是客户很懒,客户的员工更加懒。 本着让别人节省时间的原则,提倡出了让列表和Excal的单元格一样,不仅看数据还可以随时更改数据。 查资料 根据 Jeecg-Vue3 源码介绍,从而知道是基于 Vben Admin 开源项目进行改造的。 因此在 Vben…

Sulfo-CY3 NHS荧光染料的制备和表征

Sulfo-CY3 NHS(源自星戈瑞的花菁染料)荧光染料的制备和表征是确保染料质量和性能的关键步骤。制备Sulfo-CY3 NHS荧光染料&#xff1a; 原材料准备&#xff1a;准备所需的原材料&#xff0c;包括CY3 NHS ester&#xff08;或等效的前体&#xff09;&#xff0c;用于制备Sulfo-C…