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: 200MB
      max-request-size: 200MB
      enabled: true
minio:
  endpoint: http://127.0.0.1:9000
  accessKey: minioadmin
  secretKey: minioadmin
  bucketName: 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 minio
 
D:
cd D:\Program Files\minio
 
minio.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
     */
    @Bean
    public 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 {
    @Autowired
    private 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 {
    @Autowired
    private MinIoUtil minIoUtil;
    @Autowired
    private 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 = true
      this.$nextTick(() => {
        this.$refs.uploadFile.init()
      })
    }

 子组件vue页面

包含三种上传方式的切换

<template>
  <el-dialog
    title="维修处理"
    :close-on-click-modal="true"
    :visible.sync="visible"
  >
    <el-select
      size="small"
      v-model="uploadMethodValue"
      placeholder="请选择上传方式"
      clearable=""
      filterable
    >
      <el-option
        v-for="d in uploadMethod"
        :key="d.value"
        :label="d.name"
        :value="d.value"
      ></el-option>
    </el-select>

    <el-upload
      class="upload-demo"
      ref="upload"
      drag
      action="#"
      :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>
      <div
        class="el-upload__tip"
        slot="tip"
      >只能上传jpg/png文件,且不超过500kb</div>
      <div
        class="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 = true
      this.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') {
        // miniio
        this.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.filePath
          this.$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异常。该方法在实际项目开发中使用较少。

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
整合MinioSpring Boot可以通过以下几个步骤完成: 1. 首先,需要在pom.xml文件中添加Minio的依赖项。你可以使用以下代码片段添加依赖项: ```xml <dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>8.4.3</version> </dependency> ``` 2. 接下来,在application.yml(或application.properties)文件中配置Minio的连接信息。你需要提供Minio服务端的地址、访问密钥和存储桶名称。以下是一个示例: ```yaml minio: url: 129.0.0.1:9000 access-key: minioadmin secret-key: minioadmin bucket-name: ding_server ``` 3. 最后,在你的代码中使用Minio客户端库进行操作。你可以根据需要使用Minio的API来上传、下载和管理对象。以下是一个使用Minio客户端库的示例: ```java import io.minio.MinioClient; import io.minio.errors.MinioException; // 创建Minio客户端 MinioClient minioClient = new MinioClient("http://localhost:9000", "minioadmin", "minioadmin"); // 上传对象到Minio存储minioClient.putObject("your-bucket-name", "your-object-name", "/path/to/your-file"); // 下载对象从Minio存储minioClient.getObject("your-bucket-name", "your-object-name", "/path/to/save/downloaded-file"); // 列出Minio存储桶中的所有对象 Iterable<Result<Item>> results = minioClient.listObjects("your-bucket-name"); for (Result<Item> result : results) { Item item = result.get(); System.out.println(item.objectName()); } // 删除Minio存储桶中的对象 minioClient.removeObject("your-bucket-name", "your-object-name"); ``` 以上就是在Spring Boot整合Minio的基本步骤。你可以根据具体需求进行进一步的操作和配置。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [springboot整合minio](https://blog.csdn.net/qq_36090537/article/details/128100423)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *3* [SpringBoot整合Minio](https://blog.csdn.net/weixin_46573014/article/details/128476327)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值