spring boot 整合 minio存储 【使用篇】

导入依赖

		<!--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

  1. @echo off:这是批处理文件的第一行,表示关闭命令回显,即不在命令执行前显示命令本身。

  2. echo.:显示一个空行,这样可以让输出信息更加清晰。

  3. echo [信息] 运行MinIO文服务器。:输出提示信息,告诉用户即将运行MinIO文服务器。

  4. title minio:设置窗口标题为 "minio"。

  5. D:  代表进入D盘

  6. 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异常。该方法在实际项目开发中使用较少。

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

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

相关文章

python接口自动化(一)--什么是接口、接口优势、类型(详解)

简介 经常听别人说接口测试&#xff0c;接口测试自动化&#xff0c;但是你对接口&#xff0c;有多少了解和认识&#xff0c;知道什么是接口吗&#xff1f;它是用来做什么的&#xff0c;测试时候要注意什么&#xff1f;坦白的说&#xff0c;笔者之前也不是很清楚。接下来先看一下…

C# Socket通信从入门到精通(21)——TCP发送文件与接收文件 C#代码实现

1、前言 我们在开发上位机软件的过程中经常需要发送文件,本文就是介绍如何利用tcp客户端发送文件、tcp服务器端接收文件,也就是所谓的文件传输,而且本文介绍的方法具备以下特点: 1)可配置发送的文件夹和接收的文件夹路径: 2)可自动发送指定文件夹下的所有子目录和文件;…

STM32 DMA入门指导

什么是DMA DMA&#xff0c;全称直接存储器访问&#xff08;Direct Memory Access&#xff09;&#xff0c;是一种允许硬件子系统直接读写系统内存的技术&#xff0c;无需中央处理单元&#xff08;CPU&#xff09;的介入。下面是DMA的工作原理概述&#xff1a; 数据传输触发&am…

IO多路转接

1.select 初识select 系统提供 select 函数来实现多路复用输入 / 输出模型 . select 系统调用是用来让我们的程序监视多个文件描述符的状态变化的 ; 程序会停在 select 这里等待&#xff0c;直到被监视的文件描述符有一个或多个发生了状态改变 ; select函数模型 select的函…

Vue开发实例(三)项目引入Element-UI

项目引入Element-UI 一、引入Element-UI二、注册组件1、vue2使用element-ui2、vue3使用element-ui 三、使用Element组件1、轻微改造2、验证element是否生效 一、引入Element-UI npm i element-ui --save npm install element-ui -S等待安装完成 二、注册组件 1、vue2使用ele…

C++真题列表

题目解析&#xff1a;RAM是闪存&#xff0c;只要一关机一拔电&#xff0c;就会丢失数据 题目解答&#xff1a;A 题目解析&#xff1a;TXT格式是文本文档 题目解答&#xff1a;B 题目解析&#xff1a;IP地址中每一个字节的取值范围是[0~255]&#xff0c;是不可能有256的 题目…

Mongodb基础(node.js版)

一、Mongodb 介绍 Mongodb 是一个文档数据库&#xff0c;以文档形式存储数据&#xff0c;格式类似于 JSON 与 Mysql 的特点及选型对照 MongodbMysql关系类型非关系型关系型存储类型文档存储&#xff08;类似于写 Word &#xff09;表格存储 &#xff08;类似于写 Excle&…

【Python】进阶学习:pandas--isin()用法详解

【Python】进阶学习&#xff1a;pandas–isin()用法详解 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f448; 希望得到您的订阅…

midjourney提示词语法

更高级的提示可以包括一个或多个图像URL、多个文本短语和一个或更多个参数 Image Prompts 可以将图像URL添加到提示中&#xff0c;以影响最终结果的样式和内容。图像URL总是位于提示的前面。 https://docs.midjourney.com/image-prompts Text Prompt 要生成的图像的文本描述。…

C++_运算符_逻辑运算符

逻辑运算符的作用 用于根据表达式的值返回真值或假值 逻辑运算符有以下符号 示例1&#xff1a;逻辑非 示例2&#xff1a;逻辑与 总结 同真为真&#xff0c;其余为假 示例3&#xff1a;逻辑或 总结 同假为假&#xff0c;其余为真

Git 如何上传本地的所有分支

Git 如何上传本地的所有分支 比如一个本地 git 仓库里定义了两个远程分支&#xff0c;一个名为 origin&#xff0c; 一个名为 web 现在本地有一些分支是 web 远程仓库没有的分支&#xff0c;如何将本地所有分支都推送到 web 这个远程仓库上呢 git push web --all

蓝桥杯(3.2)

1209. 带分数 import java.io.*;public class Main {static BufferedReader br new BufferedReader(new InputStreamReader(System.in));static PrintWriter pw new PrintWriter(new OutputStreamWriter(System.out));static final int N 10;static int n, cnt;static int[…

云服务器租用哪家好?不要忽视第3点

注册资本&#xff1a;5亿元 权威认证&#xff1a;中央网信办云服务安全审查DJCP网络安全等级保护ITSS工信部云计算服务能力评估CSA STAR认证管理体系认证信息安全安全管理体系认证可信云服务认证可信云云主机等级评估5星 PCI-DSS支付卡行业数据安全认证 租哪家云服务器比较好&…

ssm666社区流浪动物救助领养系统的设计与开发

** &#x1f345;点赞收藏关注 → 私信领取本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345;** 一 、设计说明 1.1 课题…

如何解决微服务的数据一致性分发问题?

介绍 系统架构微服务化以后,根据微服务独立数据源的思想,每个微服务一般具有各自独立的数据源,但是不同微服务之间难免需要通过数据分发来共享一些数据,这个就是微服务的数据分发问题。Netflix/Airbnb等一线互联网公司的实践[参考附录1/2/3]表明,数据一致性分发能力,是构…

windows下安装cnpm

cnpm是淘宝团队开发的一个针对中国用户的npm镜像源&#xff0c;它是npm的一个定制版本。由于国外的npm源在国内访问速度较慢&#xff0c;所以cnpm镜像源可以提供更快的下载速度。cnpm的使用方式与npm基本相同&#xff0c;只需将npm替换为cnpm即可。 要想使用cnpm等先安装node.…

创建型模式之原型模式

一、概述 1、工作原理&#xff1a;将一个原型对象传给要发动创建的对象(即客户端对象),这个要发动创建的对象通过请求原型对象复制自己来实现创建过程 2、通过克隆方法所创建的对象是全新的对象&#xff0c;它们在内存中拥有新的地址&#xff0c;每一个克隆对象都是独立的 3…

WordPress建站入门教程:如何在本地电脑搭建WordPress网站?

前面跟大家分享了『WordPress建站入门教程&#xff1a;如何安装本地WordPress网站运行环境&#xff1f;』&#xff0c;接下来boke112百科就继续跟大家分享本地电脑如何搭建WordPress网站。 小皮面板&#xff08;phpstudy&#xff09;的“软件管理 – 网站程序”虽然可以一键部…

鸿蒙Harmony应用开发—ArkTS声明式开发(通用属性:Popup控制)

给组件绑定popup弹窗&#xff0c;并设置弹窗内容&#xff0c;交互逻辑和显示状态。 说明&#xff1a; 从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 popup弹窗的显示状态在onStateChange事件回调中反馈&#xff0c;其显…

RNA-Seq 笔记 [4]

***********************该笔记为初学者笔记&#xff0c;仅供个人参考谨慎搬运代码****************************** samtools 排序压缩和 featureCounts 生成基因计数表 SAM文件和BAM文件 1.SAM格式&#xff1a;是一种通用的比对格式&#xff0c;用来存储reads到参考序列的比…