在云服务器上搭建 MinIO 图片存储服务器及 Spring Boot 整合实现图片上传下载

一、MinIO 核心概念

MinIO 是一个高性能的分布式对象存储服务器,兼容 Amazon S3 API,具有以下特点:

  • 高性能:针对存储和检索优化

  • 轻量级:单个二进制文件即可运行

  • 云原生:支持 Kubernetes 部署

  • S3 兼容:可以直接替换 AWS S3

  • 数据保护:纠删码和加密支持

核心组件

  1. MinIO Server:存储服务主体

  2. MinIO Client (mc):命令行管理工具

  3. MinIO Console:Web 管理界面

二、MinIO 服务端搭建

1. 单机模式部署

使用docker命令拉取镜像

docker pull minio/minio:RELEASE.2023-04-28T18-11-17Z

启动命令

docker run -d \-p 9000:9000 -p 9001:9001 \-v ~/minio/data:/data \--name minio \docker.io/minio/minio:RELEASE.2023-04-28T18-11-17Z \server /data --console-address ":9001"

查看启动结果:

在自己的云服务器防火墙上开放9000和9001端口

2. . 访问管理界面

浏览器访问:http://your-server-ip:9001

默认账户密码:

username:minioadmin

password:minioadmin

三、Spring Boot 集成 MinIO

1. 添加依赖

<!-- pom.xml -->
<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.5.2</version>
</dependency>

2. 配置 MinIO 客户端

@Configuration
public class MinioConfig {@Value("${minio.endpoint}")private String endpoint;@Value("${minio.accessKey}")private String accessKey;@Value("${minio.secretKey}")private String secretKey;@Beanpublic MinioClient minioClient() {return MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();}
}

3. 配置文件

# application.yml
minio:endpoint: http://your-server-ip:9000accessKey: adminsecretKey: your-strong-passwordbucket: images

四、核心功能实现

package com.hl.mybatisplus;
​
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Item;
import org.apache.commons.compress.utils.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
​
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.List;
import java.util.concurrent.TimeUnit;
​
@RestController
@RequestMapping("/minio")
public class MinioController {@Autowiredprivate MinioClient minioClient;
​@Value("${minio.bucket}")private String bucketName;
​// 设置存储桶策略为只读公开String policy = "{\n" +"  \"Version\": \"2012-10-17\",\n" +"  \"Statement\": [\n" +"    {\n" +"      \"Effect\": \"Allow\",\n" +"      \"Principal\": \"*\",\n" +"      \"Action\": [\"s3:GetObject\"],\n" +"      \"Resource\": [\"arn:aws:s3:::" + bucketName + "/*\"]\n" +"    }\n" +"  ]\n" +"}";
​
​@RequestMapping("upload")public String uploadFile(MultipartFile file, String objectName) throws Exception {// 确保存储桶存在createBucket();// 上传文件ObjectWriteResponse response = minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build());System.out.println(response);
​String url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().method(Method.GET).bucket(bucketName).object(objectName).expiry(1, TimeUnit.HOURS).build());System.out.println("Temp URL: " + url);
​
​return objectName;}
​// 控制器示例@GetMapping("/download/{objectName}")public void downloadFile(@PathVariable String objectName, HttpServletResponse response) throws Exception {try (InputStream inputStream = downloadFile(objectName)) {response.setContentType("application/octet-stream");response.setHeader("Content-Disposition", "attachment; filename=\"" + objectName + "\"");IOUtils.copy(inputStream, response.getOutputStream());response.flushBuffer();}}
​public void createBucket() throws Exception {boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());if (!found) {// 设置存储桶策略为只读公开minioClient.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(bucketName).config(policy).build());
//            minioClient.makeBucket(MakeBucketArgs.builder()
//                    .bucket(bucketName)
//                    .build());}}public InputStream downloadFile(String objectName) throws Exception {return minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build());}}

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

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

相关文章

《深入解析:如何通过CSS集成WebGPU实现高级图形效果》

当CSS的细腻笔触遇上WebGPU的磅礴算力&#xff0c;两者如同命运交织的织工&#xff0c;以代码为丝线&#xff0c;在虚拟空间中编织出超越现实维度的灵境。这场融合不再局限于视觉呈现的革新&#xff0c;而是创造出一种能够与用户情感共鸣、突破物理法则束缚的沉浸式数字体验&am…

R 语言科研绘图 --- 环状图-汇总

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…

突破限制:实现页面内精准监听 localStorage 变更

突破限制&#xff1a;实现页面内精准监听 localStorage 变更 一、简介二、示例演示三、StorageEvent重构setItem四、CustomEvent自定义事件同一页面不同模块数据同步五、MessageChannel同一页面不同模块数据同步六、BroadcastChannel多窗口数据同步七、CustomEventBroadcastCha…

牛客AI面试破解电销招聘效率与成本双重难题

在电销行业&#xff0c;高流动性与大规模招聘需求长期困扰企业人力资源管理。传统招聘模式下&#xff0c;HR需应对海量简历筛选、多轮面试协调、主观评估偏差等挑战&#xff0c;导致招聘周期长、成本高、人才匹配度低。如何通过技术手段实现精准筛选与效率提升&#xff1f;牛客…

智慧生产管控数字化平台(源码+文档+讲解+演示)

引言 在全球化和信息化的浪潮中&#xff0c;制造业正面临着前所未有的挑战和机遇。智慧生产管控数字化平台应运而生&#xff0c;旨在通过数字化手段优化生产管控的全流程。本文将详细介绍智慧生产管控数字化平台的核心功能、技术架构以及如何通过开源代码实现二次开发&#xf…

用Tensorflow进行线性回归和逻辑回归(九)

用TensorFlow训练线性和逻辑回归模型 这一节结合前面介绍的所有TensorFlow概念来训练线性和逻辑回归模型&#xff0c;使用玩具数据集。 用TensorFlow训练模型 假如我们指明了数据点和标签的容器&#xff0c;定义了张量操作的损失函数。添加了优化器节点到计算图&#xff0c;…

使用 vue vxe-table 实现复选框禁用,根据行规则来禁用是否允许被勾选选中

使用 vue vxe-table 实现复选框禁用&#xff0c;根据行规则来禁用是否允许被勾选选中 查看官网&#xff1a;https://vxetable.cn 禁用选中 通过 checkMethod 方法控制 checkbox 是否允许用户手动勾选&#xff0c;如果被禁用&#xff0c;可以调用 setCheckboxRow 方法手动设置…

【Linux-网络】深入拆解TCP核心机制与UDP的无状态设计

&#x1f3ac; 个人主页&#xff1a;谁在夜里看海. &#x1f4d6; 个人专栏&#xff1a;《C系列》《Linux系列》《算法系列》 ⛰️ 道阻且长&#xff0c;行则将至 目录 &#x1f4da;引言 &#x1f4da;一、UDP协议 &#x1f4d6; 1.概述 &#x1f4d6; 2.特点 &#x1…

(nice!!!)(LeetCode 每日一题) 2081. k 镜像数字的和 (枚举)

题目&#xff1a;2081. k 镜像数字的和 思路&#xff1a;枚举10进制的回文串&#xff0c;然后来判断对应的k进制数是否是回文串。直到有n个满意即可。 而枚举10进制的回文串&#xff0c;从基数p(1、10、100… )开始&#xff0c;长度为奇数的回文串&#xff0c;长度为偶数的回文…

Java面试题027:一文深入了解数据库Redis(3)

Java面试题025&#xff1a;一文深入了解数据库Redis&#xff08;1&#xff09; Java面试题026&#xff1a;一文深入了解数据库Redis&#xff08;2&#xff09; 本节我们整理一下Redis高可用和消息队列使用场景的重点原理&#xff0c;让大家在面试或者实际工作中遇到这类问题时…

算法打卡 day4

4 . 高精度算法 性质&#xff1a;数组或者容器从低位往高位依次存储大整数&#xff0c;方便进位。 4.1 高精度加法 给定两个正整数&#xff08;不含前导 0&#xff09;&#xff0c;计算它们的和。 输入格式 共两行&#xff0c;每行包含一个整数。 输出格式 共一行&#xff0c;…

【笔记】Docker 配置阿里云镜像加速(公共地址即开即用,无需手动创建实例)

2025年06月25日记 【好用但慎用】Windows 系统中将所有 WSL 发行版从 C 盘迁移到 非系统 盘的完整笔记&#xff08;附 异常处理&#xff09;-CSDN博客 【笔记】解决 WSL 迁移后 Docker 出现 “starting services: initializing Docker API Proxy: setting up docker ap” 问题…

day35-Django(1)

day35-Django 3.2 前言 之前我们介绍过web应用程序和http协议,简单了解过web开发的概念。Web应用程序的本质 接收并解析HTTP请求,获取具体的请求信息处理本次HTTP请求,即完成本次请求的业务逻辑处理构造并返回处理结果——HTTP响应import socketserver = socket.socket() …

PostgreSQL全栈部署指南:从零构建企业级高可用数据库集群

PostgreSQL全栈部署指南:从零构建企业级数据库集群 前言: 本文详解了**PostgreSQL**所有的部署方式,如 yum 安装、源码编译安装、RPM包手动安装,以及如何选择适合的安装方式。适合不同的场景应用。通过高可用部署详细了解安装思路及过程,包括内网环境下的配置、主节点的创…

MQTT 和 HTTP 有什么本质区别?

MQTT 和 HTTP 的本质区别在于它们设计的初衷和核心工作模式完全不同。它们是为解决不同问题而创造的两种工具。 简单来说&#xff1a; HTTP 就像是去图书馆问问题&#xff1a;你&#xff08;客户端&#xff09;主动去找图书管理员&#xff08;服务器&#xff09;&#xff0c;…

GtkSharp跨平台WinForm实现

文章目录 跨平台架构设计跨平台项目配置GtkSharp串口通讯实现跨平台部署配置Linux系统配置macOS系统配置 相关学习资源GTK#跨平台开发跨平台.NET开发Linux开发环境macOS开发环境跨平台UI框架对比容器化部署开源项目参考性能优化与调试 跨平台架构设计 基于GTKSystem.Windows.F…

【闲谈】对于c++未来的看法

对于C未来看法 C 作为一门诞生于上世纪的编程语言&#xff0c;在软件工业发展史上扮演了不可替代的角色。尽管近年来诸如 Rust、Go、Swift、Kotlin 等现代语言相继崛起&#xff0c;C 依然在系统软件、高性能服务、嵌入式等关键领域中发挥着主力作用。本文将从 C 的当前应用前景…

【论文】云原生事件驱动架构在智能风控系统中的实践与思考

摘要 2023年6月至2024年3月,我作为某头部证券公司新一代极速交易系统的首席架构师,主导设计并落地了基于云原生事件驱动架构的全新交易风控平台。该项目旨在攻克原有系统无法支撑峰值20万笔/秒交易量、风控延迟超过3秒以及行情剧烈波动时系统崩溃等核心痛点。通过构建以Kube…

opensbi从0到1入门学习

最近要在RV64的平台上把Linux给bringup起来&#xff0c;由于当下的工作主要集中在底层硬件接口驱动、CPU的操作及RTOS应用等&#xff0c;虽然之前搞过Arm Linux的开发工作&#xff0c;但是比较基础的玩的比较少&#xff0c;所以真正要搞把系统bringup起来&#xff0c;我之前的知…

Python打卡:Day36

复习日 浙大疏锦行