zi导入依赖
<!--minio--><dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.0.3</version></dependency>
yml配置(默认配置)
spring:# 配置文件上传大小限制servlet:multipart:max-file-size: 200MBmax-request-size: 200MB
minio:endpoint: http://127.0.0.1:9000accessKey: minioadminsecretKey: minioadminbucketName: bucket-qhj
一一对应
补充:由于每次启动minio.exe要进入对应目录,很麻烦,所以可以写个批处理文件.bat
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
使用value注解装配yml配置文件中的值
@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
@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异常。该方法在实际项目开发中使用较少。