SpringBoot上传文件到Minio服务器

news2024/11/19 7:47:43

前言

本文主要介绍如何使用SpringBoot上传到minio服务器。

没什么可多说的,公司用什么咱们开发研究什么就完事了。直接分享核心代码。

核心代码

minio依赖

  <!--  minio依赖   -->
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>8.2.1</version>
        </dependency>

配置文件

首先是核心的参数,包括服务器minio地址,以及用户名密码,使用的桶名称

 # 配置minio文件上传的几个核心参数
  minio:
    minio_url: xxx
    minio_name: xxx
    minio_pass: xxx
    bucketName: xxxx

controller代码

如果只需要上传文件,只需要MultipartFile参数就够了。我的这几个参数都是为了完成业务逻辑

	@ApiOperation(value = "身份信息表-附件信息-上传文件", notes = "身份信息表-附件信息-上传文件")
    @PostMapping(value = "/upload")
    public Result<?> upload(MultipartFile file, Integer fileTypeDic, Integer fileCategoryDic) throws Exception {
        return identityFileInfoService.uploadMinio(file, fileTypeDic, fileCategoryDic);
    }

service代码

   /**
     * @Author 魏一鹤
     * @Description 上传到minio服务器
     * @Date 10:51 2022/12/20
     */
    Result<?> uploadMinio(MultipartFile file, Integer fileTypeDic, Integer fileCategoryDic) throws Exception;

serviceImpl代码

做主要的代码就是这在里,获取配置文件里面的几个参数。初始化一个minio客户端

这里面方法的部分参数和代码都是为了满足我个人需求,比如创建存放文件的年月目录层级,获取文件前后缀等。根据自己的需求灵活改变即可。

注意:一下代码进行了部分代码割舍,直接复制可能会报错,根据自己的需求灵活改变即可。

package org.jeecg.front.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.filter.FileTypeFilter;
import org.jeecg.common.util.filter.StrAttackFilter;
import org.jeecg.front.entity.IdentityFileInfo;
import org.jeecg.front.service.IdentityFileInfoService;
import org.jeecg.modules.common.FileUtils;
import org.jeecg.modules.common.IOUtils;
import org.jeecg.modules.mapper.IdentityFileInfoMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Calendar;
import java.util.Date;

import static org.jeecg.modules.common.ResultCodeStatusEnum.FAIL;
import static org.jeecg.modules.common.ResultCodeStatusEnum.SUCCESS;

/**
 * @Author 魏一鹤
 * @Description 身份信息表-附件信息service接口实现类
 * @Date 2022/12/19
 **/
@Service
public class IdentityFileInfoServiceImpl extends ServiceImpl<IdentityFileInfoMapper, IdentityFileInfo> implements IdentityFileInfoService {
    // 上传路径
    @Value(value = "${jeecg.minio.minio_url}")
    private String minioUrl;
    // 上传类型 minio
    @Value(value = "${jeecg.uploadType}")
    private String uploadType;
    // 桶名称
    @Value(value = "${jeecg.minio.bucketName}")
    private String bucketName;
    // minio用户名
    @Value(value = "${jeecg.minio.minio_name}")
    private String minioName;
    // minio密码
    @Value(value = "${jeecg.minio.minio_pass}")
    private String minioPass;
    // minio客户端
    private static MinioClient minioClient = null;
    // 系统路径 
    private String sysPath = "";

    /**
     * @Author 魏一鹤
     * @Description 上传到minio服务器
     * @Date 10:51 2022/12/20
     */
    @Override
    public Result<?> uploadMinio(MultipartFile file, Integer identityInfoId, Integer fileTypeDic) throws Exception {
        Result<IdentityFileInfo> result = new Result<>();
        Calendar calendar = Calendar.getInstance();
        // 当前年份,用于拼接系统路径
        int year = calendar.get(Calendar.YEAR);
        // 当前月份,注意加1,用于拼接系统路径
        int month = calendar.get(Calendar.MONTH) + 1;
        // 格式化时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        String time = sdf.format(new Date());
        // 上传后的完整路径
        String filePath = "";
        // 文件大小
        long size = file.getSize();
        // 拼接的系统上传路径
        String spliceSysPath = sysPath + year + "/" + month;
        spliceSysPath = StrAttackFilter.filter(spliceSysPath);
        FileTypeFilter.fileTypeFilter(file);
        InputStream stream = null;
        try {
            // 初始化minio客户端
            initMinio(minioUrl, minioName, minioPass);
            stream = file.getInputStream();
            // 获取原文件名 这个文件名用于文件路径拼接
            String orgName = file.getOriginalFilename();
            String objectName = null;
            // 获取原文件名 这个文件名就是原文件名
            String originalFilename = null;
            // 文件前缀
            String prefix = null;
            // 文件后缀
            String suffix = null;
            if (StringUtils.isNotBlank(orgName)) {
                originalFilename = file.getOriginalFilename();
                prefix = orgName.substring(0, orgName.lastIndexOf("."));
                // 文件后缀
                suffix = orgName.substring(orgName.lastIndexOf("."));
                objectName = spliceSysPath + "/" + prefix + "_" + time + suffix;
            }
            PutObjectArgs objectArgs = PutObjectArgs.builder()
                    .object(objectName)
                    .bucket(bucketName)
                    .contentType("application/octet-stream")
                    .stream(stream, stream.available(), -1).build();
            minioClient.putObject(objectArgs);
            filePath = minioUrl + bucketName + "/" + objectName;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            if (stream != null) {
                stream.close();
            }
        }
        return result;
    }

 


    /**
     * 初始化客户端
     *
     * @param minioUrl
     * @param minioName
     * @param minioPass
     * @return
     */
    private static MinioClient initMinio(String minioUrl, String minioName, String minioPass) {
        if (minioClient == null) {
            try {
                minioClient = MinioClient.builder()
                        .endpoint(minioUrl)
                        .credentials(minioName, minioPass)
                        .build();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return minioClient;
    }


}

测试

这样访问接口的url,选择File类型的文件,就能进行文件上传了:

在这里插入图片描述

在桶里面也是可以看到的

在这里插入图片描述

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

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

相关文章

ArcGIS基础实验操作100例--实验91栅格欧式分配

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 空间分析篇--实验91 栅格欧式分配 目录 一、实验背景 二、实验数据 三、实验步骤 &#xff08;1&…

第01讲:什么是kubernetes

一、什么是k8s&#xff1f; kubernetes&#xff0c;简称 K8s&#xff0c;是用 8 代替 8 个字符“ubernete”而成的缩写。是一个开源 的&#xff0c;用于管理云平台中多个主机上的容器化的应用&#xff0c;Kubernetes 的目标是让部署容器化的 应用简单并且高效(powerful),Kubern…

马蹄集 时刻求和

时刻求和 难度&#xff1a;白银 0时间限制&#xff1a;1秒 巴占用内存&#xff1a;64M 输入正整数N和M,空格分隔。把他们看作在12小时制的时刻&#xff08;小时&#xff09;求 和并输出&#xff0c;输出最小列宽为3列。 #include<bits/stdc.h> using namespace std; int…

linux篇【14】:网络http协议

目录 一.HTTP协议 1.认识URL &#xff08;1&#xff09;域名->必须被转化成为IP &#xff08;2&#xff09;URL中可以省略的部分 ①端口号可缺省 ②登录信息可以省略 ③当我们访问自己的服务器时&#xff0c;https可省略&#xff0c;端口号不可省 &#xff08;3&#x…

6.2、客户/服务器方式(C/S)对等方式(P2P方式)

网络应用程序运行在处于网络边缘的不同的端系统上&#xff0c;通过彼此间的通信来共同完成某项任务。 开发一种新的网络应用首先要考虑的问题就是网络应用程序在各种端系统上的组织方式和它们之间的关系。\color{red}网络应用程序在各种端系统上的组织方式和它们之间的关系。网…

设计模式_创建型模式 -《建造者模式》

设计模式_创建型模式 -《建造者模式》 笔记整理自 黑马程序员Java设计模式详解&#xff0c; 23种Java设计模式&#xff08;图解框架源码分析实战&#xff09; 概述 将一个复杂对象的构建与表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。 分离了部件的构造&#…

Golang.org/x库初探2——text库

Golang有一个很有意思的官方库&#xff0c;叫golang.org/x&#xff0c;x可能是extends&#xff0c;experimental&#xff0c;总之是一些在官方库中没有&#xff0c;但是又很有用的库。最近花点时间把这里有用的介绍一下。 Golang.org/x库初探1——image库Golang.org/x库初探2—…

原创,探店,混剪,带货,获客,发布,更新,呆头鹅批量剪辑软件

一天轻松剪辑2000条&#xff0c;视频批量生成工具&#xff0c;短视频带货&#xff0c;电商卖家&#xff0c;媒体运营多场景应用视频剪辑分镜音频合成&#xff0c;一次解决&#xff01; 对于广大自媒体玩家最关心的话题&#xff0c;用了这个AI全自动呆头鹅批量视频剪辑软件做出来…

骑电动车不戴头盔识别抓拍系统 yolov7

骑电动车不戴头盔识别抓拍系统通过Python基于YOLOv7网络深度学习技术&#xff0c;对现场画面中骑电动车不戴头盔识别抓拍包括骑乘人员和带乘人员。YOLOv7 在 5 FPS 到 160 FPS 范围内&#xff0c;速度和精度都超过了所有已知的目标检测器&#xff0c;并在V100 上&#xff0c;30…

如何设置等高线坐标系并输出

如何设置等高线坐标系并输出发布时间&#xff1a;2018-01-17 版权&#xff1a;投影设置及数据导出矢量等高线生成完成后&#xff08;详细生成过程参加上一章节&#xff1a;矢量等高线生成&#xff09;,我们就能够设置投影和导出等高线数据。投影设置我们生成等高线默认的坐标是…

Rust之错误处理(一):无法恢复的错误panic!

开发环境 Windows 10Rust 1.66.1VS Code 1.74.3项目工程 这里继续沿用上次工程rust-demo 错误处理 错误是软件生活中的一个事实&#xff0c;所以Rust有一些处理出错情况的功能。在许多情况下&#xff0c;Rust要求你承认错误的可能性&#xff0c;并在你的代码编译前采取一些…

Google结构化数据

为什么要向网页添加结构化数据&#xff1f; 添加结构化数据可让您获得对用户更有吸引力的搜索结果&#xff0c;并可能会鼓励用户与您的网站进行更多互动&#xff0c;这就是富媒体搜索结果。 以下是一些为网站实现了结构化数据的案例研究&#xff1a; Rotten Tomatoes 为 10 万…

【学习笔记之Linux】工具之gdb

背景知识&#xff1a; 首先我们要知道&#xff0c;程序的发布一共有两种模式&#xff0c;一种是debug模式&#xff0c;是我们程序员自己编写代码的模式&#xff0c;可以进行调试&#xff0c;这个模式下编译出来的程序是包含调试信息的&#xff1b;一种是release模式&#xff0c…

AntV G6 组织图使用(后端渲染数据)

一、业务场景&#xff1a; 点击按钮&#xff0c;跳转页面并显示该数据的组织架构图&#xff08;类似于粒子效果&#xff09; 二、问题描述&#xff1a; 初始写死的数据能显示&#xff0c;但是从接口请求到的数据赋上值 渲染不了 三、具体实现步骤&#xff1a; &#xff08;1&…

python GUI And Tkinter 01

目录 一、基础介绍 二、创建窗口 1、创建完窗口后还需要知道窗口的相关属性 2、widget相关控件 3、原本tkinter有的Widget。 4、widget的共同属性 1. Configuration 2. Event Processing 3. Event callbacks 4. Alarm handlersafter(time,callback)&#xff1a;间隔指定时间后调…

Python logging 库的『完整教程』

前言 本文的标题是『完整』。所谓『完整』&#xff0c;大意是想表达&#xff1a;提炼出一组最小的经验组合&#xff0c;并且能够快速应用于工程中&#xff0c;能 work&#xff0c;甚至能完美地 work。这篇文章就是想要做到『如何能完美地work』。 初衷 最原始的初衷就是&…

nmap 扫描数据分析

本案22端口为开放端口&#xff0c;110为未开放端口 Wireshark上使用下面的表达式 ip.addr192.168.104.127 and ip.addr192.168.104.61 and tcp.port22 ip.addr192.168.104.127 and ip.addr192.168.104.61 and tcp.port110 命令一、 nmap -sS SYN-->SYN ACK-->RST …

电脑技巧:Windows这些自带应用尽量不要删,否则影响系统运行

目录 第一种&#xff1a;带有“microsoft”字样的软件尽量不卸载。 第二种&#xff1a;带有“Intel”或者“英特尔”的程序名称不要卸载。 第三种&#xff1a;windows驱动程序包尽量不要卸载 第四种&#xff1a;Adobe flash player不建议卸载 当电脑太卡&#xff0c;运行变…

C/C++ - 从代码到可执行程序的过程

&#xff08;1&#xff09;预编译 主要处理源代码文件中的以“#”开头的预编译指令。处理规则见下&#xff1a; 删除所有的#define&#xff0c;展开所有的宏定义。处理所有的条件预编译指令&#xff0c;如“#if”、“#endif”、“#ifdef”、“#elif”和“#else”。处理“#inc…

简单工厂模式

简单工厂模式所谓组件&#xff1a;从设计上讲&#xff0c;组件就是能完成一定功能的封装体。小到一个类&#xff0c;大到一个系统&#xff0c;都可以称为组件&#xff0c;因为一个小系统放到更大的系统里面去&#xff0c;也就当个组件而已。模式定义&#xff1a;提供一个创建对…