当前位置: 首页 > news >正文

springboot+minio 文件上传

前期准备

需要先安装minio文件服务器,请参考我上一篇文章

pom.xml 版本

本次使用的是springboot2.7.16 版本,
minio 版本是8.2.2

    <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.16</version><relativePath/></parent><dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.2.2</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.11</version></dependency>

配置minio服务

minio.endpoint=**********
minio.accessKey=******
minio.secretKey=*******
minio.bucketName=shuangningzixun
# 单个文件上传的最大值
spring.servlet.mutipart.max-file-size=200MB
# 整个请求体上传的文件大小
spring.servlet.mutipart.max-request-size=500MB

其中endpoint 为本地安装的minio服务地址,形式为IP+端口
accessKey和secretKey为用户名密码
桶名称则是在minio服务上新增的桶名称。

minio配置类

package com.example.demo.config;import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@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;@Beanpublic MinioClient minioClient() {MinioClient minioClient = MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();return minioClient;}
}

minio配置实体类

package com.example.demo.config;import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@ConfigurationProperties(prefix="minio")
@Component
@Getter
@Setter
public class Minio {private String url;private String username;private String password;private String bucketName;}

minio下载服务类

package com.example.demo.service;import com.example.demo.config.Minio;
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.UUID;@Component
public class MinioService {@Autowiredprivate MinioClient minioClient;@Autowiredprivate Minio minio;public String uploadFile(MultipartFile file) throws IOException {//判断捅是否存在String url=null;try {boolean bucketExists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(minio.getBucketName()).build());if (!bucketExists){//如果不存在,就创建捅minioClient.makeBucket(MakeBucketArgs.builder().bucket(minio.getBucketName()).build());}String yyyyMMdd = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-mm-dd"));String uuid = UUID.randomUUID().toString();String filename = yyyyMMdd +"/"+file.getOriginalFilename();//minioClient.putObject(PutObjectArgs.builder().bucket(minio.getBucketName()).object(uuid).stream(file.getInputStream(),file.getSize(),-1).contentType(file.getContentType()).build());url  = minio.getUrl()+"/"+minio.getBucketName()+"/"+filename;return url;} catch (Exception e) {}finally {file.getInputStream().close();}return url;}
}

minio 上传文件工具类

package com.example.demo.utils;import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.io.InputStream;@Component
public class MinioUtils {@Autowiredprivate MinioClient minioClient;public InputStream getObject(String bucketName, String objectName) throws Exception {return minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build());}
}

文件控制器

package com.example.demo.controller;import com.example.demo.common.ApiResult;
import com.example.demo.config.Minio;
import com.example.demo.service.MinioService;
import com.example.demo.utils.MinioUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;@RestController
@RequestMapping("/file")
@Slf4j
public class FileController {@Autowiredprivate MinioService minioService;@Autowiredprivate MinioUtils minioUtils;@Autowiredprivate Minio minio;/*** 文件上传接口*/@PostMapping("/upload")public ApiResult<Void> upload(@RequestParam("file")MultipartFile multipartFile) throws Exception{minioService.uploadFile(multipartFile);return null;}/*** 文件下载接口*/@GetMapping("/download")public void  download(@RequestParam("fileName")String fileName,HttpServletResponse response) {try {InputStream fileInputStream = minioUtils.getObject(minio.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.info("下载失败",e);}}
}

postman测试

在这里插入图片描述
可以在minio控制台查询到已经上传的文件。
到此一个简单的文件上传下载服务就算成功了

相关文章:

  • 【随笔4】心情——复杂
  • 一个普通双非女生的秋招之路
  • 轻松学EntityFramework Core--Entity Framework Core 简介
  • 重生之 SpringBoot3 入门保姆级学习(06、属性绑定)
  • c语言如何向文件写入字符串
  • PTA 判断两个矩阵相等
  • 【白盒测试】单元测试的理论基础及用例设计技术(6种)详解
  • ubuntu下交叉编译安卓FFmpeg 和 官方指导链接
  • Python筑基之旅专栏(导航)
  • 【MySQL精通之路】InnoDB(6)-磁盘结构
  • LeetCode题练习与总结:将有序数组转换为二叉搜索树--108
  • YoloV9改进策略:卷积篇|使用PConv替换YoloV8中的卷积|即插即用,简单高效
  • 【MySQL精通之路】InnoDB(18)-备份与恢复
  • DOS学习-目录与文件应用操作经典案例-ren
  • Python小游戏——俄罗斯方块
  • 【React系列】如何构建React应用程序
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • chrome扩展demo1-小时钟
  • Druid 在有赞的实践
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • LeetCode18.四数之和 JavaScript
  • Linux链接文件
  • Python 反序列化安全问题(二)
  • 订阅Forge Viewer所有的事件
  • 对话:中国为什么有前途/ 写给中国的经济学
  • 回顾 Swift 多平台移植进度 #2
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • 手机端车牌号码键盘的vue组件
  • 推荐一个React的管理后台框架
  • 微服务框架lagom
  • ​数据结构之初始二叉树(3)
  • #1015 : KMP算法
  • #微信小程序:微信小程序常见的配置传值
  • $var=htmlencode(“‘);alert(‘2“); 的个人理解
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (函数)颠倒字符串顺序(C语言)
  • (四)js前端开发中设计模式之工厂方法模式
  • (转)EOS中账户、钱包和密钥的关系
  • (转)iOS字体
  • (转)大型网站架构演变和知识体系
  • (转)全文检索技术学习(三)——Lucene支持中文分词
  • (转载)Linux 多线程条件变量同步
  • .bat批处理(九):替换带有等号=的字符串的子串
  • .net core docker部署教程和细节问题
  • .net core 调用c dll_用C++生成一个简单的DLL文件VS2008
  • .NET WebClient 类下载部分文件会错误?可能是解压缩的锅
  • .NET 给NuGet包添加Readme
  • .Net 中Partitioner static与dynamic的性能对比
  • .NET 中选择合适的文件打开模式(CreateNew, Create, Open, OpenOrCreate, Truncate, Append)
  • .NET/C# 判断某个类是否是泛型类型或泛型接口的子类型
  • .netcore如何运行环境安装到Linux服务器
  • .NET的微型Web框架 Nancy
  • .NET和.COM和.CN域名区别
  • // an array of int
  • :“Failed to access IIS metabase”解决方法