springboot+minio 文件上传

news2024/9/23 9:27:05

前期准备

需要先安装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;

    @Bean
    public 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 {

    @Autowired
    private MinioClient minioClient;

    @Autowired
    private 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 {

    @Autowired
    private 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 {
    @Autowired
    private MinioService minioService;

    @Autowired
    private MinioUtils minioUtils;

    @Autowired
    private 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控制台查询到已经上传的文件。
到此一个简单的文件上传下载服务就算成功了

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

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

相关文章

1071.字符串的最大公因子

对于字符串s和t&#xff0c;只有在s t t t ... t t&#xff08;t自身连接1次或多次&#xff09;时&#xff0c;我们才认定 “t能除尽s”。 给定两个字符串str1和str2。返回最长字符串x&#xff0c;要求满足x能除尽str1且x能除尽str2 。 示例 1&#xff1a; 输入&#xf…

上位机图像处理和嵌入式模块部署(f103 mcu原理图)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 从linux卡片电脑转到mcu领域,第一个需要适应的估计就是原理图。之前学习linux的时候,我们大概只需要知道一些接口就好了,比如电源键、usb、网口、hdmi口、音频口、tf卡槽等等,整…

使用Java 读取PDF表格数据并保存到TXT或Excel

目录 导入相关Java库 Java读取PDF表格数据并保存到TXT Java读取PDF表格数据并保存到Excel 在日常工作中&#xff0c;我们经常需要处理来自各种来源的数据。其中&#xff0c;PDF 文件是常见的数据来源之一。这类文件通常包含丰富的信息&#xff0c;其中可能包含重要的表格数据…

冯喜运:5.27黄金暴跌大阴后出现“暂定符”今日黄金原油操作策略

【黄金消息面分析】&#xff1a;金价虽然有大阴线暴跌&#xff0c;但依然属于超买后的调整而非熊市&#xff0c;对中长线投资者来说只是市场洗牌。因此&#xff0c;在出现企稳迹象之后&#xff0c;随时关注反弹时机的启动。未来几日&#xff0c;黄金空头可能在进一步发力之前需…

pdf拆分成多个文件 pdf拆分成一页一页

pdf拆分成多个文件的方法。在现代办公环境中&#xff0c;PDF文件因其跨平台、保持格式一致等特性&#xff0c;成为了广泛使用的文件格式。然而&#xff0c;有时我们需要对PDF文件进行拆分&#xff0c;以便更好地管理和使用其中的内容。本文将详细介绍PDF拆分的方法和步骤&#…

智能改写工具,一键改写文章效率非常高

在当今快节奏的时代&#xff0c;效率成为了人们追求的重要目标之一。在文章创作领域&#xff0c;智能改写工具的出现为我们带来了极大的便利&#xff0c;它的高效率一键改写优势可以帮助创作者在几秒的时间里完成文章改写的工作&#xff0c;从此&#xff0c;也让创作者们实现了…

小明同学的考试分数统计:总分、平均分与方差计算进阶

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、原始方法介绍与问题发现 原始方法存在的问题 二、优化方案&#xff1a;使用列表简化代…

【OpenVINO™】在C#中使用 OpenVINO™ 部署 YOLOv10 模型实现目标

文章目录 1. 前言1.1 OpenVINO™ C# API1.2 YOLOv10 2. 模型获取2.1 源码下载2.2 配置环境2.3 下载模型 3. Yolov10 项目配置3.1 项目创建与环境配置3.2 定义模型预测方法3.2.1 定义目标检测模型方法3.2.2 使用OpenVINO™ 预处理接口编译模型 3.2 模型预测方法调用 4. 项目运行…

Java通过Html(ftl模板)生成PDF实战

Java通过Html(freemarker模板)生成PDF实战, 可支持商用 技术架构 springboot freemarker [pdfbox] flying-saucer-pdf 生成流程&#xff1a; freemarker: 根据数据填充ftl模板文件&#xff0c;得到包含有效数据的html文件&#xff08;包含页眉页脚页码的处理&#xff0c…

深入剖析—【服务器硬件】与【Nginx配置】:从基础到实战

服务器硬件部分&#xff1a; Processor (CPU)&#xff1a;服务器的计算核心&#xff0c;负责处理数据和执行程序。Memory (RAM)&#xff1a;用于暂时存储和快速访问数据&#xff0c;决定了系统的运行速度和并发处理能力。Storage (HDD/SSD)&#xff1a;长期存储数据的设备&…

高性能、超小型的电源模块——TP2L-3W系列,3W 1.5KVDC 3KVDC 隔离宽范围输入,单、双输出 DC/DC 电源模块

TP2L-3W系列是一款高性能、超小型的电源模块&#xff0c;宽范围2:1,4:1输入&#xff0c;输出有稳压和连续短路保护功能&#xff0c;隔离电压为1.5KVDC、3KVDC工作温度范围为–40℃到85℃。特别适合对输出电压的精度有严格要求的地方&#xff0c;外部遥控功能对您的设计又多一项…

行业分析---造车新势力之小鹏汽车

1 背景 在之前的博客中&#xff0c;笔者分析了苹果《行业分析---我眼中的Apple Inc.》&#xff0c;随后也分析了电动汽车公司特斯拉《行业分析---马斯克的Tesla》和蔚来汽车《行业分析---造车新势力之蔚来汽车》&#xff0c;看到有不少读者朋友对此类文章也有些兴趣。 那么本篇…

基于springboot实现旅游管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现旅游管理系统演示 摘要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本旅游管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助使用者在…

Docker基础篇之入门使用

文章目录 1. Docker的基本组成2. Docker平台架构3. 阿里云镜像加速4. Docker的Hello World入门案例5. 总结 1. Docker的基本组成 Docker的基本组成主要是有四部分&#xff0c;分别是镜像、容器和仓库。 镜像&#xff1a;Docker镜像就是一个只读的模版&#xff0c;镜像可以用来…

huggingface笔记: accelerate estimate-memory 命令

探索可用于某一机器的潜在模型时&#xff0c;了解模型的大小以及它是否适合当前显卡的内存是一个非常复杂的问题。为了缓解这个问题&#xff0c;Accelerate 提供了一个 命令行命令 accelerate estimate-memory。 accelerate estimate-memory {MODEL_NAME} --library_name {LIBR…

kettle学习之表的输入输出

需求 把表A里的数据传送到表B中&#xff0c;在此之前&#xff0c;清空表B内的数据 表输入 执行SQL脚本 表输出

OrangePi AIpro上手初体验:

OrangePi AIpro上手初体验&#xff1a; 1.基本外观及功能接口简介2.点亮OrangePi AIpro开发板3.OrangePi AIpro功能体验3.1.目标检测3.2.OCR文字识别3.3.图像的曝光增强3.4.系统的整体性能(运行ROS) 4.OrangePi AIpro体验总结4.1.硬件及软件生态&#xff1a;4.2.使用体验及性能…

独立乙游井喷成新趋势,真来抢市场还是只画大饼?

国产乙游市场又迎来了新变化。 进入5月份&#xff0c;独立乙女游戏如雨后春笋般冒了出来&#xff0c;两、三个人组成的制作组&#xff0c;没有任何程序协助和资金支持&#xff0c;全靠为爱发电来打造一款乙女游戏&#xff0c;成为了今夏乙游市场的新趋势。 目前已经有独立乙游…

Android Studio 中gradle的bin和all区别

1.在android studio中设置安装gradle时&#xff0c;真各种版本看到眼花缭乱&#xff0c;还有疑惑gradle-*.*-all.zip与gradle-*.*-bin.zip的区别是什么。下面解压如下: bin&#xff1a; all: 其实&#xff0c;用bin就可以了&#xff0c;all文件就是多了docs(文档)和src(源码)两…

007、字符串_命令

字符串类型是Redis最基础的数据结构。首先键都是字符串类型&#xff0c;而且 其他几种数据结构都是在字符串类型基础上构建的&#xff0c;所以字符串类型能为其 他四种数据结构的学习奠定基础。 设置值 set key value [ex seconds] [px milliseconds] [nx|xx] 下面操作设置键…