SpringBoot 整合 MinIO 实现文件存储——私有化 OSS 方案
项目里总少不了文件上传下载的功能——用户头像、合同附件、产品图片。用阿里云 OSS 方便但要钱自己存服务器又麻烦。MinIO 是一个开源的对象存储服务兼容 S3 协议可以私有化部署性能和功能完全不输商业 OSS。一、MinIO 简介MinIO vs 其他方案 阿里云 OSS → 按量付费省心但长期用成本高 FastDFS → 部署复杂社区不活跃 MinIO → 开源免费部署简单性能强悍号称读写 183GB/s 自己存磁盘 → 简单但不支持分布式备份困难MinIO 的优势兼容 AWS S3 接口SDK 直接可用部署简单一个 Docker 命令启动支持分布式部署多台机器做集群有 Web 管理界面开源且社区活跃二、安装 MinIO1. Docker 一键部署推荐dockerrun-d\--nameminio\-p9000:9000\-p9001:9001\-eMINIO_ROOT_USERadmin\-eMINIO_ROOT_PASSWORDadmin123456\-vD:\minio\data:/data\quay.io/minio/minio server /data --console-address:9001启动后访问API 端口http://localhost:9000管理后台http://localhost:9001账号 admin / 密码 admin1234562. 在管理台创建 Bucket登录管理后台 → 点击「Create Bucket」→ 输入名称如my-bucket→ 确认。三、SpringBoot 集成 MinIO1. 引入依赖dependencygroupIdio.minio/groupIdartifactIdminio/artifactIdversion8.5.7/version/dependency2. 配置minio:endpoint:http://localhost:9000access-key:adminsecret-key:admin123456bucket:my-bucket3. 配置类ConfigurationpublicclassMinIOConfig{Value(${minio.endpoint})privateStringendpoint;Value(${minio.access-key})privateStringaccessKey;Value(${minio.secret-key})privateStringsecretKey;BeanpublicMinioClientminioClient(){returnMinioClient.builder().endpoint(endpoint).credentials(accessKey,secretKey).build();}}四、文件上传下载1. 文件上传服务ServicepublicclassFileService{AutowiredprivateMinioClientminioClient;Value(${minio.bucket})privateStringbucket;/** * 上传文件 * param file 上传的文件 * param objectName 存储的文件名如 avatar/2026/06/abc123.jpg */publicStringupload(MultipartFilefile,StringobjectName)throwsException{// 检查 bucket 是否存在booleanfoundminioClient.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());if(!found){minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());}// 上传minioClient.putObject(PutObjectArgs.builder().bucket(bucket).object(objectName).stream(file.getInputStream(),file.getSize(),-1).contentType(file.getContentType()).build());// 返回可访问的 URLreturnendpoint/bucket/objectName;}/** * 上传文件自动生成文件名 */publicStringupload(MultipartFilefile)throwsException{// 原始文件名StringoriginalFilenamefile.getOriginalFilename();// 扩展名StringextoriginalFilename.substring(originalFilename.lastIndexOf(.));// 新文件名日期 UUIDStringobjectNameDateUtil.today()/IdUtil.simpleUUID()ext;returnupload(file,objectName);}/** * 上传文件指定目录前缀 */publicStringupload(MultipartFilefile,Stringprefix,LonguserId)throwsException{StringextoriginalFilename.substring(originalFilename.lastIndexOf(.));StringobjectNameprefix/userId/IdUtil.simpleUUID()ext;returnupload(file,objectName);}}2. ControllerRestControllerRequestMapping(/file)publicclassFileController{AutowiredprivateFileServicefileService;PostMapping(/upload)publicResultVOStringupload(RequestParam(file)MultipartFilefile){if(file.isEmpty()){returnResultVO.error(400,请选择文件);}try{// 校验文件大小10MBif(file.getSize()10*1024*1024){returnResultVO.error(400,文件不能超过10MB);}// 校验文件类型只允许图片和 PDFStringcontentTypefile.getContentType();if(contentTypenull||!contentType.startsWith(image/)!contentType.equals(application/pdf)){returnResultVO.error(400,不支持的文件格式);}StringurlfileService.upload(file);returnResultVO.success(url);}catch(Exceptione){returnResultVO.error(500,上传失败: e.getMessage());}}PostMapping(/upload/avatar)publicResultVOStringuploadAvatar(RequestParam(file)MultipartFilefile,RequestParamLonguserId){try{StringurlfileService.upload(file,avatar,userId);returnResultVO.success(url);}catch(Exceptione){returnResultVO.error(500,上传失败);}}}五、文件删除publicvoiddelete(StringobjectName)throwsException{minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(objectName).build());}publicvoiddeleteByUrl(StringfileUrl){// 从 URL 中提取 objectName// http://localhost:9000/my-bucket/avatar/1/xxx.jpgStringprefixendpoint/bucket/;StringobjectNamefileUrl.substring(prefix.length());delete(objectName);}六、获取文件列表publicListStringlistFiles(Stringprefix){ListStringfilesnewArrayList();IterableResultItemresultsminioClient.listObjects(ListObjectsArgs.builder().bucket(bucket).prefix(prefix)// 按前缀过滤.recursive(true)// 递归查询.build());for(ResultItemresult:results){files.add(result.get().objectName());}returnfiles;}七、生成临时访问链接有些文件不想公开访问可以生成带有效期的临时链接publicStringgetPresignedUrl(StringobjectName,intexpiryMinutes)throwsException{returnminioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().bucket(bucket).object(objectName).method(Method.GET).expiry(expiryMinutes,TimeUnit.MINUTES).build());}八、前端上传formiduploadFormenctypemultipart/form-datainputtypefilenamefileidfileInputbuttontypebuttononclickuploadFile()上传/button/formscriptasyncfunctionuploadFile(){constfileInputdocument.getElementById(fileInput);constformDatanewFormData();formData.append(file,fileInput.files[0]);constrespawaitfetch(/file/upload,{method:POST,body:formData,});constresultawaitresp.json();if(result.code200){console.log(文件地址:,result.data);// 回显图片document.getElementById(preview).srcresult.data;}}/script九、Nginx 代理 MinIO生产环境中MinIO 一般不直接暴露端口而是通过 Nginx 代理server { listen 80; server_name file.example.com; location / { proxy_pass http://127.0.0.1:9000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }配置后访问http://file.example.com/my-bucket/xxx.jpg即可查看文件。十、MinIO vs 阿里云 OSS 怎么选场景推荐方案个人/小项目没有公网服务器阿里云 OSS省心公司项目服务器在本地机房MinIO省成本高并发、大流量场景阿里云 OSSCDN 加速数据隐私要求高政务、金融MinIO 私有化部署学习/练手项目MinIODocker 几分钟搞定一句话不差钱上阿里云 OSS想省钱且能自己维护服务器的用 MinIO功能体验几乎一样。 觉得有用的话点赞 关注【张老师技术栈】吧每周更新 Java/Python/爬虫 实战干货不让你白来。

相关新闻

示波器抓 I2C 时序:如何一眼看出 ACK 没拉低?

示波器抓 I2C 时序:如何一眼看出 ACK 没拉低?

摘要:I2C 通信失败,逻辑分析仪看着“有波形”,但示波器一看全是破绽。很多时候,问题不在“有没有波形”,而在 ACK 信号的“坡度”和“幅值”。本文将教你识别那些“看起来像 0,实际是 1”的假低电平。一、真…

2026/6/30 5:28:21阅读更多 →
世界模型的PopLang底座:当物理AI遇上ibbot智体机灵,每台手机都能成为“认知推演沙盘”

世界模型的PopLang底座:当物理AI遇上ibbot智体机灵,每台手机都能成为“认知推演沙盘”

世界模型的PopLang底座:当物理AI遇上ibbot智体机灵,每台手机都能成为“认知推演沙盘”文/宁明一、世界模型:所有AI概念的“终局缝合器”元宇宙吹过的牛、数字孪生画过的饼、自动驾驶立过的flag、人形机器人许下的诺言——你有没有发现&#x…

2026/6/30 5:28:21阅读更多 →
AI期刊论文写作工具哪个好?2026年主流工具横向测评

AI期刊论文写作工具哪个好?2026年主流工具横向测评

花费数月打磨论文,却因为参考文献格式被退稿;想投核心期刊,内容深度总差一点;面对各种AI写作工具,也不知道哪个能真帮上忙。我反复对比了市面上多款AI写作工具,逢君学术是目前专为国内期刊投稿设计的AI论文…

2026/6/30 5:28:21阅读更多 →
【企业级提示词工程落地白皮书】:覆盖金融/医疗/客服场景的12个可复用Prompt模式库(限免72小时)

【企业级提示词工程落地白皮书】:覆盖金融/医疗/客服场景的12个可复用Prompt模式库(限免72小时)

更多请点击: https://codechina.net 第一章:提示词工程的基本概念与核心价值 提示词工程(Prompt Engineering)是指通过系统性设计、优化和迭代自然语言指令,引导大语言模型生成更准确、可靠、可控输出的技术实践。它并…

2026/6/30 7:28:30阅读更多 →
【企业级API成本管控白皮书】:从千次调用$0.002到$0.0008——基于真实生产环境的7层压缩策略

【企业级API成本管控白皮书】:从千次调用$0.002到$0.0008——基于真实生产环境的7层压缩策略

更多请点击: https://codechina.net 第一章:API成本管控的战略价值与行业痛点 在云原生与微服务架构深度普及的今天,API 已成为企业数字能力输出的核心载体。每一次外部调用、内部服务间通信乃至第三方集成,都在悄然累积可观的基…

2026/6/30 7:28:30阅读更多 →
深度解锁NVIDIA驱动隐藏功能:Profile Inspector实战调优指南

深度解锁NVIDIA驱动隐藏功能:Profile Inspector实战调优指南

深度解锁NVIDIA驱动隐藏功能:Profile Inspector实战调优指南 【免费下载链接】nvidiaProfileInspector 项目地址: https://gitcode.com/gh_mirrors/nv/nvidiaProfileInspector 在NVIDIA显卡性能优化领域,Profile Inspector作为一款开源工具&…

2026/6/30 7:28:30阅读更多 →
【2024最新版ChatGPT API深度解析】:v1/chat/completions接口底层协议拆解与流式响应性能优化实测

【2024最新版ChatGPT API深度解析】:v1/chat/completions接口底层协议拆解与流式响应性能优化实测

更多请点击: https://kaifayun.com 第一章:ChatGPT API演进脉络与v1/chat/completions核心定位 OpenAI的API体系经历了从实验性接口( /v1/engines/{engine}/completions)到标准化REST架构( /v1/chat/completions&…

2026/6/30 7:28:30阅读更多 →
3分钟破解Office付费壁垒:Ohook钩子技术完全指南

3分钟破解Office付费壁垒:Ohook钩子技术完全指南

3分钟破解Office付费壁垒:Ohook钩子技术完全指南 【免费下载链接】ohook An universal Office "activation" hook with main focus of enabling full functionality of subscription editions 项目地址: https://gitcode.com/gh_mirrors/oh/ohook …

2026/6/30 7:28:30阅读更多 →
深入解析MSPM0L架构:总线、内存与启动机制的设计哲学与实战

深入解析MSPM0L架构:总线、内存与启动机制的设计哲学与实战

1. 架构概览与设计哲学在嵌入式领域摸爬滚打十几年,我经手过的MCU架构少说也有几十种。从早期的8位机到如今复杂的32位Cortex-M系列,一个深刻的体会是:芯片的底层架构,直接决定了你后期开发的“天花板”和“舒适度”。很多工程师拿…

2026/6/30 7:23:30阅读更多 →
AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

6个月前的2025年12月,Boris Cherny 公开宣布自己卸载了 IDE。一时间,Vibe Coding 成了全行业最热的话题。6个月后,当我们回过头来拉一份真实账本,发现事情远没有"一句话生成一个App"那么浪漫。本文从产品经理和研发两个…

2026/6/30 4:03:30阅读更多 →
审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

引言:审计结束三个月了,审计员的权限还没关某城商行每年按照监管要求开展至少一次数据安全审计。审计期间,内审部门需要抽样检查各类业务数据——交易流水、客户信息、员工操作日志、权限配置记录。这些数据分布在不同系统中,审计…

2026/6/30 4:36:27阅读更多 →
为什么你需要Destiny 2 Solo Enabler:技术原理与实战指南

为什么你需要Destiny 2 Solo Enabler:技术原理与实战指南

为什么你需要Destiny 2 Solo Enabler:技术原理与实战指南 【免费下载链接】Destiny-2-Solo-Enabler Repo containing the C# and XAML code for the D2SE program. Included is also the dependency for the program, and image asset. 项目地址: https://gitcode…

2026/6/30 0:02:58阅读更多 →
第六章:PowerPoint 2010 核心功能与实战应用 —— 从入门到精通

第六章:PowerPoint 2010 核心功能与实战应用 —— 从入门到精通

1. PowerPoint 2010基础操作全攻略 刚接触PowerPoint 2010时,很多人会被它复杂的界面吓到。其实只要掌握几个核心区域,就能快速上手。我最开始用PPT时,经常找不到功能按钮在哪,后来发现主要操作都集中在顶部功能区。 工作窗口主要…

2026/6/30 0:02:58阅读更多 →
XGBoost超参数实战:从理论到调优策略

XGBoost超参数实战:从理论到调优策略

1. XGBoost超参数基础认知 第一次接触XGBoost时,我被它那密密麻麻的参数列表吓到了。这感觉就像面对一架波音747的驾驶舱——每个按钮都可能有神奇的效果,但按错了就可能坠机。经过多年实战,我发现其实掌握十几个核心参数就能解决90%的问题。…

2026/6/30 0:02:59阅读更多 →