• springboot项目若以集成minio文件服务


    完整代码,可直接复制使用。

    1、maven依赖包minio

     
            <dependency>
                <groupId>io.miniogroupId>
                <artifactId>minioartifactId>
                <version>8.2.2version>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2、目录结构如下图:
    在这里插入图片描述
    3、配置类(MinioConfig.java)

    package com.ruoyi.web.core.config;
    
    import io.minio.MinioClient;
    import lombok.Data;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.stereotype.Component;
    
    /**
     * Minio 配置信息
     * @author ruoyi
     */
    @Data
    @Component
    @ConfigurationProperties(prefix = "minio")
    public class MinioConfig {
        /**
         * 服务地址
         */
        private String url;
    
        /**
         * 用户名
         */
        private String accessKey;
    
        /**
         * 密码
         */
        private String secretKey;
    
        /**
         * 存储桶名称
         */
        private String bucketName;
    
        /**
         * 外联有效时间
         */
        private Integer expires;
    
        public String getUrl() {
            return url;
        }
    
        public void setUrl(String url) {
            this.url = url;
        }
    
        public Integer getExpires() {
            return expires;
        }
    
        public void setExpires(Integer expires) {
            this.expires = expires;
        }
    
        public String getAccessKey() {
            return accessKey;
        }
    
        public void setAccessKey(String accessKey) {
            this.accessKey = accessKey;
        }
    
        public String getSecretKey() {
            return secretKey;
        }
    
        public void setSecretKey(String secretKey) {
            this.secretKey = secretKey;
        }
    
        public String getBucketName() {
            return bucketName;
        }
    
        public void setBucketName(String bucketName) {
            this.bucketName = bucketName;
        }
    
        @Bean
        public MinioClient getMinioClient() {
            return MinioClient.builder().endpoint(url).credentials(accessKey, secretKey).build();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87

    4、minio工具类(MinioUtil.java):

    package com.ruoyi.web.app.utils;
    
    import com.ruoyi.common.exception.ServiceException;
    import io.minio.*;
    import io.minio.http.Method;
    import io.minio.messages.Bucket;
    import lombok.Cleanup;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.web.multipart.MultipartFile;
    import java.io.InputStream;
    import java.util.List;
    import java.util.Optional;
    import java.util.concurrent.TimeUnit;
    
    /**
     * MinioUtil
     * @author JWB
     * @date 2023/9/4
     */
    @Slf4j
    @Component
    public class MinioUtil {
    
        @Autowired
        private MinioClient client;
    
    
        /**
         * 校验bucket
         */
        public boolean checkBucket(String bucketName) {
            try {
                return client.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            } catch (Exception e) {
                log.error("MINIO校验BUCKET ==> 校验BUCKET失败!", e);
                return false;
            }
        }
    
        /**
         * 上传文件
         */
        public void uploadFile(MultipartFile file, String bucketName, String filePath) {
            //判断文件是否为空
            if (null == file || file.getSize() == 0) {
                throw new ServiceException("文件为空!");
            }
            //判断存储桶是否存在
            if (!checkBucket(bucketName)) {
                throw new ServiceException("文件存储桶不存在!");
            }
            try {
                //开始上传
                @Cleanup
                InputStream inputStream = file.getInputStream();
                client.putObject(PutObjectArgs.builder().bucket(bucketName).object(filePath).stream(inputStream, file.getSize(), -1).contentType(file.getContentType()).build());
            } catch (Exception e) {
                log.error("MINIO上传文件 ==> 上传失败!", e);
                throw new ServiceException("上传失败!");
            }
        }
    
        /**
         * 获取全部bucket
         */
        public List<Bucket> getBuckets() {
            try {
                return client.listBuckets();
            } catch (Exception e) {
                log.error("MINIO获取全部BUCKET ==> 获取失败!", e);
                throw new ServiceException("获取失败!");
            }
        }
    
        /**
         * 根据bucketName获取信息
         */
        public Bucket getBucket(String bucketName) {
            try {
                Bucket bucket = null;
                Optional<Bucket> first = client.listBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst();
                if (first.isPresent()) {
                    bucket = first.get();
                }
                return bucket;
            } catch (Exception e) {
                log.error("MINIO获取信息 ==> 获取信息失败!", e);
                throw new ServiceException("获取信息失败!");
            }
        }
    
        /**
         * 根据bucketName删除信息
         */
        public void removeBucket(String bucketName) {
            try {
                client.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
                log.info("MINIO删除BUCKET ==> 删除BUCKET成功!");
            } catch (Exception e) {
                log.error("MINIO删除BUCKET ==> 删除BUCKET失败!", e);
                throw new ServiceException("删除BUCKET失败!");
            }
        }
    
        /**
         * 获取文件外链
         * @param bucketName bucket名称
         * @param filePath 文件名称
         * @param expires 过期时间 <=7
         * @return url
         */
        public String getFileUrl(String bucketName, String filePath, Integer expires) {
            try {
                return client.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().method(Method.GET).bucket(bucketName).object(filePath).expiry(expires, TimeUnit.HOURS).build());
            } catch (Exception e) {
                log.error("MINIO获取文件外链 ==> 获取文件外链失败!", e);
                throw new ServiceException("获取文件外链失败!");
            }
        }
    
        /**
         * 获取文件
         * @param bucketName bucket名称
         * @param filePath 文件名称
         * @return ⼆进制流
         */
        public InputStream getFile(String bucketName, String filePath) {
            try {
                return client.getObject(GetObjectArgs.builder().bucket(bucketName).object(filePath).build());
            } catch (Exception e) {
                log.error("MINIO获取文件 ==> 获取文件失败!", e);
                throw new ServiceException("获取文件失败!");
            }
        }
    
        /**
         * 下载文件
         * @param bucketName bucket名称
         * @param filePath 文件路径
         * @param fileName 文件名称
         */
        public void downloadFile(String bucketName, String filePath, String fileName) {
            try {
                client.downloadObject(DownloadObjectArgs.builder().bucket(bucketName).object(filePath).filename(fileName).build());
            } catch (Exception e) {
                log.error("MINIO获取文件 ==> 下载文件失败!", e);
                throw new ServiceException("下载文件失败!");
            }
        }
    
        /**
         * 获取文件信息和对象的元数据
         * @param bucketName bucket名称
         * @param filePath 文件名称
         */
        public StatObjectResponse getFileInfo(String bucketName, String filePath) {
            try {
                return client.statObject(StatObjectArgs.builder().bucket(bucketName).object(filePath).build());
            } catch (Exception e) {
                log.error("MINIO获取文件信息 ==> 获取文件信息失败!", e);
                throw new ServiceException("获取文件信息失败!");
            }
        }
    
        /**
         * 删除文件(单个)
         * @param bucketName bucket名称
         * @param filePath 文件名称
         */
        public void removeFile(String bucketName, String filePath) {
            try {
                client.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(filePath).build());
                log.info("MINIO删除文件 ==> 删除文件成功!");
            } catch (Exception e) {
                log.error("MINIO删除文件 ==> 删除文件失败!", e);
                throw new ServiceException("删除文件失败!");
            }
        }
    
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183

    5、文件上传工具类(FileUploadUtils.java):

    package com.ruoyi.web.app.utils;
    
    import com.ruoyi.common.exception.file.FileNameLengthLimitExceededException;
    import com.ruoyi.common.exception.file.FileSizeLimitExceededException;
    import com.ruoyi.common.exception.file.InvalidExtensionException;
    import com.ruoyi.common.utils.DateUtils;
    import com.ruoyi.common.utils.StringUtils;
    import com.ruoyi.common.utils.file.MimeTypeUtils;
    import com.ruoyi.common.utils.uuid.Seq;
    import org.apache.commons.io.FilenameUtils;
    import org.springframework.web.multipart.MultipartFile;
    
    import java.io.File;
    import java.io.IOException;
    import java.nio.file.Paths;
    import java.util.Objects;
    
    /**
     * 文件上传工具类
     * @author ruoyi
     */
    public class FileUploadUtils {
        /**
         * 默认大小 100M
         */
        public static final long DEFAULT_MAX_SIZE = 100 * 1024 * 1024;
    
        /**
         * 默认的文件名最大长度 100
         */
        public static final int DEFAULT_FILE_NAME_LENGTH = 100;
    
    
    
        /**
         * 根据文件路径上传
         * @param baseDir 相对应用的基目录
         * @param file 上传的文件
         * @return 文件名称
         * @throws IOException
         */
        public static String upload(String baseDir, MultipartFile file) throws IOException {
            try {
                return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
            } catch (Exception e) {
                throw new IOException(e.getMessage(), e);
            }
        }
    
        /**
         * 文件上传
         * @param baseDir 相对应用的基目录
         * @param file 上传的文件
         * @param allowedExtension 上传文件类型
         * @return 返回上传成功的文件名
         * @throws FileSizeLimitExceededException 如果超出最大大小
         * @throws FileNameLengthLimitExceededException 文件名太长
         * @throws IOException 比如读写文件出错时
         * @throws InvalidExtensionException 文件校验异常
         */
        public static String upload(String baseDir, MultipartFile file, String[] allowedExtension)
                throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
                InvalidExtensionException {
            int fileNameLength = Objects.requireNonNull(file.getOriginalFilename()).length();
            if (fileNameLength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH) {
                throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
            }
    
            assertAllowed(file, allowedExtension);
    
            String fileName = extractFilename(file);
    
            String absPath = getAbsoluteFile(baseDir, fileName).getAbsolutePath();
            file.transferTo(Paths.get(absPath));
            return getFilePath(baseDir, fileName);
        }
    
        /**
         * 编码文件名
         */
        public static String extractFilename(MultipartFile file) {
            return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(),
                    FilenameUtils.getBaseName(file.getOriginalFilename()), Seq.getId(Seq.uploadSeqType), getExtension(file));
        }
    
        public static File getAbsoluteFile(String uploadDir, String fileName) {
            File file = new File(uploadDir + File.separator + fileName);
            if (!file.exists()) {
                if (!file.getParentFile().exists()) {
                    file.getParentFile().mkdirs();
                }
            }
            return file;
        }
    
    
    
        public static String getFilePath(String uploadDir, String fileName) {
            return uploadDir + "/" + fileName;
        }
    
        /**
         * 文件大小校验
         * @param file 上传的文件
         * @throws FileSizeLimitExceededException 如果超出最大大小
         * @throws InvalidExtensionException
         */
        public static void assertAllowed(MultipartFile file, String[] allowedExtension)
                throws FileSizeLimitExceededException, InvalidExtensionException {
            long size = file.getSize();
            if (size > DEFAULT_MAX_SIZE) {
                throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024);
            }
    
            String fileName = file.getOriginalFilename();
            String extension = getExtension(file);
            if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension)) {
                if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION) {
                    throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension, fileName);
                } else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION) {
                    throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension, fileName);
                } else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION) {
                    throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension, fileName);
                } else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION) {
                    throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension, fileName);
                } else {
                    throw new InvalidExtensionException(allowedExtension, extension, fileName);
                }
            }
    
        }
    
        /**
         * 判断MIME类型是否是允许的MIME类型
         * @param extension 文件类型
         * @param allowedExtension 允许的文件类型集合
         * @return boolean
         */
        public static boolean isAllowedExtension(String extension, String[] allowedExtension) {
            for (String str : allowedExtension) {
                if (str.equalsIgnoreCase(extension)) {
                    return true;
                }
            }
            return false;
        }
    
        /**
         * 获取文件名的后缀
         * @param file 表单文件
         * @return 后缀名
         */
        public static String getExtension(MultipartFile file) {
            String extension = FilenameUtils.getExtension(file.getOriginalFilename());
            if (StringUtils.isEmpty(extension)) {
                extension = MimeTypeUtils.getExtension(Objects.requireNonNull(file.getContentType()));
            }
            return extension;
        }
    
        /**
         * 校验文件
         * @param file 上传的文件
         * @throws FileSizeLimitExceededException 如果超出最大大小
         * @throws FileNameLengthLimitExceededException 文件名太长
         * @throws InvalidExtensionException 文件校验异常
         */
        public static void checkFile(MultipartFile file) throws FileSizeLimitExceededException,
                FileNameLengthLimitExceededException, InvalidExtensionException {
            if (Objects.requireNonNull(file.getOriginalFilename()).length() > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH) {
                throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
            }
    
            assertAllowed(file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
        }
    
        /**
         * 生成文件路径
         */
        public static String getFilePath(MultipartFile file) {
            return StringUtils.format("{}/{}", DateUtils.datePath(), renameFilename(file));
        }
    
         /**
          * 编码文件名
          */
        public static String renameFilename(MultipartFile file) {
            return StringUtils.format("{}_{}.{}", FilenameUtils.getBaseName(file.getOriginalFilename()), Seq.getId(Seq.uploadSeqType), getExtension(file));
        }
    
    
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194

    6、FileInfoMapper.xml 文件

    
    DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.ruoyi.web.app.mapper.FileInfoMapper">
    
        <resultMap type="com.ruoyi.web.app.domain.FileInfo" id="BaseResult">
            <result property="fileId" column="file_id" jdbcType="BIGINT"/>
            <result property="systemType" column="system_type" jdbcType="VARCHAR"/>
            <result property="bucketName" column="bucket_name" jdbcType="VARCHAR"/>
            <result property="fileName" column="file_name" jdbcType="VARCHAR"/>
            <result property="fileSize" column="file_size" jdbcType="BIGINT"/>
            <result property="filePath" column="file_path" jdbcType="VARCHAR"/>
            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
            <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
            <result property="delFlag" column="del_flag" jdbcType="CHAR"/>
        resultMap>
    
        <sql id="BaseSelect">
            select file_id,
                   system_type,
                   bucket_name,
                   file_name,
                   file_size,
                   file_path,
                   create_time,
                   update_time,
                   del_flag
            from file_info
        sql>
    
        <select id="findList" resultMap="BaseResult">
            <include refid="BaseSelect"/>
            <where>
                <if test="systemType != null and systemType != ''">
                    and system_type = #{systemType,jdbcType=VARCHAR}
                if>
                <if test="bucketName != null and bucketName != ''">
                    and bucket_name = #{bucketName,jdbcType=VARCHAR}
                if>
                <if test="fileName != null and fileName != ''">
                    and file_name like concat('%', #{fileName}, '%')
                if>
                <if test="filePath != null and filePath != ''">
                    and file_path = #{filePath,jdbcType=VARCHAR}
                if>
            where>
        select>
    
        <select id="findById" parameterType="Long" resultMap="BaseResult">
            <include refid="BaseSelect"/>
            where file_id = #{fileId,jdbcType=BIGINT}
        select>
    
        <select id="findByIds" resultMap="BaseResult">
            <include refid="BaseSelect"/>
            where file_id in
            <foreach item="fileId" collection="fileIds" open="(" separator="," close=")">
                #{fileId}
            foreach>
        select>
    
        <insert id="add" parameterType="com.ruoyi.web.app.domain.FileInfo" useGeneratedKeys="true" keyProperty="fileId">
            insert into file_info
            <trim prefix="(" suffix=")" suffixOverrides=",">
                <if test="systemType != null and systemType != ''">
                    system_type,
                if>
                <if test="bucketName != null and bucketName != ''">
                    bucket_name,
                if>
                <if test="fileName != null and fileName != ''">
                    file_name,
                if>
                <if test="fileSize != null">
                    file_size,
                if>
                <if test="filePath != null and filePath != ''">
                    file_path,
                if>
                    create_time,
                <if test="updateTime != null">
                    update_time,
                if>
            trim>
            <trim prefix="values (" suffix=")" suffixOverrides=",">
                <if test="systemType != null and systemType != ''">
                    #{systemType,jdbcType=VARCHAR},
                if>
                <if test="bucketName != null and bucketName != ''">
                    #{bucketName,jdbcType=VARCHAR},
                if>
                <if test="fileName != null and fileName != ''">
                    #{fileName,jdbcType=VARCHAR},
                if>
                <if test="fileSize != null">
                    #{fileSize,jdbcType=BIGINT},
                if>
                <if test="filePath != null and filePath != ''">
                    #{filePath,jdbcType=VARCHAR},
                if>
                    sysdate(),
                <if test="updateTime != null">
                    #{updateTime,jdbcType=TIMESTAMP},
                if>
            trim>
        insert>
    
        <update id="update" parameterType="com.ruoyi.web.app.domain.FileInfo">
            update file_info
            <trim prefix="SET" suffixOverrides=",">
                <if test="systemType != null and systemType != ''">
                    system_type = #{systemType,jdbcType=VARCHAR},
                if>
                <if test="bucketName != null and bucketName != ''">
                    bucket_name = #{bucketName,jdbcType=VARCHAR},
                if>
                <if test="fileName != null and fileName != ''">
                    file_name = #{fileName,jdbcType=VARCHAR},
                if>
                <if test="fileSize != null">
                    file_size = #{fileSize,jdbcType=BIGINT},
                if>
                <if test="filePath != null and filePath != ''">
                    file_path = #{filePath,jdbcType=VARCHAR},
                if>
                <if test="createTime != null">
                    create_time = #{createTime,jdbcType=TIMESTAMP},
                if>
                <if test="updateTime != null">
                    update_time = #{updateTime,jdbcType=TIMESTAMP},
                if>
                <if test="delFlag != null and delFlag != ''">
                    del_flag = #{delFlag,jdbcType=CHAR},
                if>
            trim>
            where file_id = #{fileId,jdbcType=BIGINT}
        update>
    
        <update id="updateStatus">
            update file_info
            set update_time = sysdate(),
                del_flag = '1'
            where file_id = #{fileId,jdbcType=BIGINT}
        update>
    
        <delete id="deleteById" parameterType="Long">
            delete
            from file_info
            where file_id = #{fileId,jdbcType=BIGINT}
        delete>
    
        <delete id="deleteByIds" parameterType="Long">
            delete from file_info where file_id in
            <foreach item="fileId" collection="fileIds" open="(" separator="," close=")">
                #{fileId}
            foreach>
        delete>
    mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159

    7、FileInfoMapper.java

    package com.ruoyi.web.app.mapper;
    
    import com.ruoyi.web.app.domain.FileInfo;
    import org.apache.ibatis.annotations.Mapper;
    
    
    /**
     * 图片管理
     * @author jwb
     * @date 2023-08-04
     */
    @Mapper
    public interface FileInfoMapper
    {
        /**
         * 保存
         * @param fileInfo
         * @return
         */
        int  add(FileInfo fileInfo);
    
        /**
         * 删除
         * @param fileId
         */
        int deleteById(Long fileId);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    8、IMinioFileService.java

    package com.ruoyi.web.app.service;
    
    
    import com.ruoyi.web.app.domain.FileInfo;
    import com.ruoyi.web.app.domain.FileSimple;
    import org.springframework.web.multipart.MultipartFile;
    
    
    /**
     * MinIO文件上传接口
     * @author jwb
     */
    public interface IMinioFileService {
    
    
        /**
         * 文件上传
         * @return 简单文件信息
         * @throws Exception 异常
         */
        FileSimple upload(MultipartFile file, String flag) throws Exception;
    
    
        /**
         * 获取文件外链
         * @return 文件外链
         */
        String getFileUrl(FileInfo file);
    
        /**
         * 删除文件(单个)
         * @param file 文件
         */
        int removeFile(FileInfo file);
    
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    9、MinioFileServiceImpl.java

    package com.ruoyi.web.app.service.impl;
    
    import com.ruoyi.common.utils.spring.SpringUtils;
    import com.ruoyi.web.app.domain.FileInfo;
    import com.ruoyi.web.app.domain.FileSimple;
    import com.ruoyi.web.app.mapper.FileInfoMapper;
    import com.ruoyi.web.app.service.IMinioFileService;
    import com.ruoyi.web.app.utils.FileUploadUtils;
    import com.ruoyi.web.app.utils.MinioUtil;
    import com.ruoyi.web.core.config.MinioConfig;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Primary;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    import org.springframework.web.multipart.MultipartFile;
    
    /**
     * Minio 文件存储
     *
     * @author jwb
     * @date 2023/7/26
     */
    @Primary
    @Service
    public class MinioFileServiceImpl implements IMinioFileService {
    
        private static MinioConfig minio = SpringUtils.getBean(MinioConfig.class);
        @Autowired
        private MinioUtil minioUtil;
    
        @Autowired
        private FileInfoMapper fileInfoMapper;
    
    
        @Override
        public FileSimple upload(MultipartFile file, String flag) throws Exception {
            //校验文件
            FileUploadUtils.checkFile(file);
            //生成文件路径
            String filePath = FileUploadUtils.getFilePath(file);
            minioUtil.uploadFile(file,minio.getBucketName(), filePath);
            //创建数据实体对象
            FileInfo fileInfo = new FileInfo();
            fileInfo.setSystemType(flag);
            fileInfo.setFileName(file.getOriginalFilename());
            fileInfo.setFileSize(file.getSize());
            fileInfo.setBucketName(minio.getBucketName());
            fileInfo.setFilePath(filePath);
            fileInfoMapper.add(fileInfo);
            //设置返回参数
            FileSimple fileSimple = new FileSimple();
            String fileUrl = minio.getUrl()+"/"+minio.getBucketName()+"/"+filePath;
            fileSimple.setFileId(fileInfo.getFileId());
            fileSimple.setSystemType(flag);
            fileSimple.setFileBucket(minio.getBucketName());
            fileSimple.setFileName(file.getOriginalFilename());
            fileSimple.setFilePath(filePath);
            fileSimple.setFileUrl(fileUrl);
            return fileSimple;
        }
    
    
        @Override
        public String getFileUrl(FileInfo file) {
            return minioUtil.getFileUrl(file.getBucketName(),file.getFilePath(),minio.getExpires());
        }
    
    
        @Override
        @Transactional(rollbackFor = Exception.class)
        public int removeFile(FileInfo file) {
            //删除文件
            minioUtil.removeFile(file.getBucketName(), file.getFilePath());
            //删除文件信息
            int i = fileInfoMapper.deleteById(file.getFileId());
            return i;
        }
    
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81

    10、PictureManageController.java

    package com.ruoyi.web.app.controller;
    
    import com.ruoyi.common.core.domain.AjaxResult;
    import com.ruoyi.web.app.domain.FileInfo;
    import com.ruoyi.web.app.domain.FileSimple;
    import com.ruoyi.web.app.service.IMinioFileService;
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiOperation;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    import org.springframework.web.multipart.MultipartFile;
    
    
    /**
     * 图片管理
     * @author jwb
     * @date 2023-08-04
     */
    
    @CrossOrigin
    @RestController
    @RequestMapping("/app/pic")
    @Api(value = "PictureManageController", tags = "4 图片文件管理", description = "4 图片文件管理",position = 1)
    public class PictureManageController
    {
    
        @Autowired
        private IMinioFileService minioFileService;
    
    
        /**
         * 图片上传
         * @param file
         * @return
         */
        @PostMapping("/upload")
        @ApiOperation(value = "图片文件管理-图片上传", notes = "图片文件管理-图片上传")
        public FileSimple upload(@RequestParam("files") MultipartFile file, @RequestParam("flag") String flag) throws Exception {
            FileSimple fileSimple =minioFileService.upload(file,flag);
            return fileSimple;
        }
    
        /**
         * 删除文件
         * @param file
         * @return
         */
        @PostMapping("/removeFile")
        @ApiOperation(value = "图片文件管理-删除文件", notes = "图片文件管理-删除文件")
        public AjaxResult removeFile(FileInfo file) throws Exception {
            return AjaxResult.success(minioFileService.removeFile(file));
        }
    
        /**
         * 预览文件
         * @param file
         * @return
         */
        @PostMapping("/getFileUrl")
        @ApiOperation(value = "预览文件", notes = "预览文件")
        public AjaxResult getFileUrl(FileInfo file) throws Exception {
            return AjaxResult.success(minioFileService.getFileUrl(file));
        }
    
    
    
    
    
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71

    11、实体类FileSimple.java

    package com.ruoyi.web.app.domain;
    
    import io.swagger.annotations.ApiModel;
    import io.swagger.annotations.ApiModelProperty;
    
    import java.io.Serializable;
    
    @ApiModel("文件简单信息")
    public class FileSimple implements Serializable {
    
        private static final long serialVersionUID = 1324375213483853453L;
    
        @ApiModelProperty(value = "主键ID", name = "fileId")
        private Long fileId;
    
        @ApiModelProperty(value = "系统类型", name = "systemType")
        private String systemType;
    
        @ApiModelProperty(value = "文件桶", name = "bucketName")
        private String fileBucket;
    
        @ApiModelProperty(value = "文件名称", name = "fileName")
        private String fileName;
    
        @ApiModelProperty(value = "文件路径", name = "filePath")
        private String filePath;
    
        @ApiModelProperty(value = "文件url", name = "fileUrl")
        private String fileUrl;
    
    
        public Long getFileId() {
            return fileId;
        }
    
        public void setFileId(Long fileId) {
            this.fileId = fileId;
        }
    
        public String getSystemType() {
            return systemType;
        }
    
        public void setSystemType(String systemType) {
            this.systemType = systemType;
        }
    
        public String getFileBucket() {
            return fileBucket;
        }
    
        public void setFileBucket(String fileBucket) {
            this.fileBucket = fileBucket;
        }
    
        public String getFileName() {
            return fileName;
        }
    
        public void setFileName(String fileName) {
            this.fileName = fileName;
        }
    
        public String getFilePath() {
            return filePath;
        }
    
        public void setFilePath(String filePath) {
            this.filePath = filePath;
        }
    
        public String getFileUrl() {
            return fileUrl;
        }
    
        public void setFileUrl(String fileUrl) {
            this.fileUrl = fileUrl;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80

    12、实体类 FileInfo.java

    package com.ruoyi.web.app.domain;
    
    import io.swagger.annotations.ApiModel;
    import io.swagger.annotations.ApiModelProperty;
    import lombok.Data;
    
    import java.io.Serializable;
    import java.util.Date;
    
    @Data
    @ApiModel("文件信息")
    public class FileInfo implements Serializable {
    
        private static final long serialVersionUID = 9203478790053741271L;
    
        @ApiModelProperty(value = "主键ID", name = "fileId")
        private Long fileId;
    
        @ApiModelProperty(value = "系统类型", name = "systemType")
        private String systemType;
    
        @ApiModelProperty(value = "文件桶", name = "bucketName")
        private String bucketName;
    
        @ApiModelProperty(value = "文件名称", name = "fileName")
        private String fileName;
    
        @ApiModelProperty(value = "文件大小", name = "fileSize")
        private Long fileSize;
    
        @ApiModelProperty(value = "文件路径", name = "filePath")
        private String filePath;
    
        @ApiModelProperty(value = "创建时间", name = "createTime")
        private Date createTime;
    
        @ApiModelProperty(value = "修改时间", name = "updateTime")
        private Date updateTime;
    
        @ApiModelProperty(value = "删除标志", name = "delFlag")
        private String delFlag;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    13、file_info表见表语句

    /*
     Navicat Premium Data Transfer
     Date: 08/09/2023 16:05:15
    */
    
    SET NAMES utf8mb4;
    SET FOREIGN_KEY_CHECKS = 0;
    
    -- ----------------------------
    -- Table structure for file_info
    -- ----------------------------
    DROP TABLE IF EXISTS `file_info`;
    CREATE TABLE `file_info`  (
      `file_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '文件ID',
      `system_type` varchar(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '系统类型',
      `bucket_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '文件桶',
      `file_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '文件名称',
      `file_size` bigint(20) NOT NULL COMMENT '文件大小',
      `file_path` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '文件路径',
      `create_time` datetime NOT NULL COMMENT '创建时间',
      `update_time` datetime NULL DEFAULT NULL COMMENT '修改时间',
      `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '删除标志(0未删除 1已删除)',
      PRIMARY KEY (`file_id`) USING BTREE
    ) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '公共文件表' ROW_FORMAT = Dynamic;
    
    SET FOREIGN_KEY_CHECKS = 1;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    14、yml配置文件信息:
    在这里插入图片描述

    最后贴一下效果图:
    请求:
    在这里插入图片描述
    minio客户端:上传结果
    在这里插入图片描述
    创作不易,大家帮忙关注一下我的公众号 休憩一下
    在这里插入图片描述

  • 相关阅读:
    怎么解决大量用户来访问,而且耗时能控制在20ms内(标签-腾讯云)
    java基础:异常篇
    MATLAB环境下基于离散小波变换的心电信号伪影去除及PQRST波检测
    添加滚动彩色提醒通知公告代码
    Nginx线程池剖析
    Apache Paimon 文件管理
    闵帆老师《论文写作》课程之心得体会
    【Vue】模块基本语法「上篇」
    Kafka3.0.0版本——文件清理策略
    Matter over Wi-Fi: Raspberry Pi 4开发环境设置
  • 原文地址:https://blog.csdn.net/qq_41060647/article/details/132762501