SpringBoot+Vue3整合minio,实现分布式文件存储

文章目录

基本所有的软件项目都会需要文件存储功能,图片、视频存储。

几种常用的文件存储

经常用的几种方案,直接存在本地文件夹,开发一个简单的系统当然没有问题。随机系统所需的资源变多,这种情况显然是不可能的。这种适合做一个简单的demo,毕设之类的的系统。

使用第三方的存储服务,如阿里云的oss,十分的方便管理。但是是收费的,如果经费充足也可以考虑。

使用HDFS ,分布式文件存储放方案,大数据领域的文件存储框架,过程配置很繁琐,对于新手来说很不友好。

minio 是一个非常轻量的服务,可以很简单的和其他应用的结合使用,它兼容亚马逊 S3 云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等。

还提供了许多语言的SDK,开发较为方便。

MinIO集群采用去中心化共享架构,每个结点是对等关系,通过Nginx可对MinIO进行负载均衡访问。

安装和使用minio

在linux上面配置mioio过于繁琐。在windows上面也可以运行。

minio的官网:dl.min.io/server/minio/release/windows-amd64/

首先下载minio,下载后是一个.exe文件

在cmd窗口中运行

java 复制代码
//minio.exe   server 启动服务器  后面是对应的节点也就是数据存储的位置,如果上线了就是服务器的地址
minio.exe server E:\develop\data\data1 E:\develop\data\data2 E:\develop\data\data3 E:\develop\data\data4


访问mino

java 复制代码
在浏览器中输入:http://localhost:9000  跳转到登录页面 账号和密码都是 minioadmin

登录进去后;

设置bucket为公有public,可以外部进行访问的。

文件的地址就是 ip地址+端口号9000+文件的相对地址

SpringBoot整合minio

1.导入minio的maven坐标。

java 复制代码
<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>8.4.3</version>
</dependency>

2.配置yml文件

minio:
  endpoint: http://127.0.0.1:9000  #文件的前缀 数据存储文件地址应该是相对地址,便于以后更换服务器
  accessKey: minioadmin
  secretKey: minioadmin
  bucket:
    files: mediafiles
    videofiles: video

在springBootTest中编写程序

//创建一个minioClient
static MinioClient minioClient =
        MinioClient.builder()
                .endpoint("http://127.0.0.1:9000")
                .credentials("minioadmin", "minioadmin")
                .build();

3.注册bean,需要用minclient。

java 复制代码
import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//注入到bean中去
@Configuration
public class MinioConfig {

    @Value("${minio.endpoint}")
    private String endpoint;
    @Value("${minio.accessKey}")
    private String accessKey;
    @Value("${minio.secretKey}")
    private String secretKey;

    @Bean
    public MinioClient minioClient() {
        return MinioClient.builder()
        .endpoint(endpoint)
        .credentials(accessKey, secretKey)
        .build();
    }
}

FileController

java 复制代码
import com.j256.simplemagic.ContentInfo;
import com.j256.simplemagic.ContentInfoUtil;
import com.njitzx.service.FileService;
import com.njitzx.util.Result;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;

@RestController
@RequestMapping(value = "/upload")
@Slf4j
public class FileController {
    private String bucket = "bucket";
    @Autowired
    private FileService fileService;

    @Value("${minio.endpoint}")
    private String endpoint;

    /**
     * 要有一个文件存储的目录?如果判断文件是否已经存在
     */

    /**
     * file 前端传过来的文件
     */
    @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Result<String> upload(@RequestParam("file") MultipartFile file) throws Exception {
        log.info("开始上传文件");
        System.out.println(file.getOriginalFilename());
        String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        File tempFile = File.createTempFile("temp", suffix);
        file.transferTo(tempFile);
        String floadName = fileService.upload(tempFile);
        String url = endpoint + "/" + bucket + "/" + floadName;
        return Result.success(url);
    }

    public static String getMimeType(String extension) {
        if (extension == null)
            extension = "";
        //根据扩展名取出mimeType
        ContentInfo extensionMatch = ContentInfoUtil.findExtensionMatch(extension);
        //通用mimeType,字节流
        String mimeType = MediaType.APPLICATION_OCTET_STREAM_VALUE;
        if (extensionMatch != null) {
            mimeType = extensionMatch.getMimeType();
        }
        return mimeType;
    }
    /**
     * 删除文件
     */
}
java 复制代码
import com.j256.simplemagic.ContentInfo;
import com.j256.simplemagic.ContentInfoUtil;
import com.njitzx.service.FileService;

import io.minio.MinioClient;
import io.minio.UploadObjectArgs;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.io.File;

import java.io.FileInputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

@Service
@Slf4j
public class FileServiceImpl implements FileService {
    @Autowired
    MinioClient minioClient;

    private String bucket = "bucket";

    @Override
    public String upload(File tempFile) {
        String filename = tempFile.getName();
        System.out.println(filename);
        String extension = filename.substring(filename.lastIndexOf("."));
        String objectname = getDefaultFolderPath() + getFileMd5(tempFile) + extension;
        System.out.println(objectname);
        try {
            UploadObjectArgs uploadObjectArgs = UploadObjectArgs.builder()
            .bucket(bucket).
            object(objectname).
            filename(tempFile.getAbsolutePath()).contentType(getMimeType(extension)).build();
            minioClient.uploadObject(uploadObjectArgs);

            log.info("上传成功");
            return objectname;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static String getMimeType(String extension) {
        if (extension == null)
            extension = "";
        //根据扩展名取出mimeType
        ContentInfo extensionMatch = ContentInfoUtil.findExtensionMatch(extension);
        //通用mimeType,字节流
        String mimeType = MediaType.APPLICATION_OCTET_STREAM_VALUE;
        if (extensionMatch != null) {
            mimeType = extensionMatch.getMimeType();
        }
        return mimeType;
    }

    public static String getFileMd5(File file) {
        try {
            FileInputStream fileInputStream = new FileInputStream(file);
            String filemd5 = DigestUtils.md5DigestAsHex(fileInputStream);
            return filemd5;
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    private String getDefaultFolderPath() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String folder = sdf.format(new Date()).replaceAll("-", "/") + "/";
        return folder;
    }
}
相关推荐
等一场春雨35 分钟前
springboot 3 websocket react 系统提示,选手实时数据更新监控
spring boot·websocket·react.js
weisian1511 小时前
Redis篇--常见问题篇7--缓存一致性2(分布式事务框架Seata)
redis·分布式·缓存
荆州克莱1 小时前
Golang的性能监控指标
spring boot·spring·spring cloud·css3·技术
AI人H哥会Java2 小时前
【Spring】控制反转(IoC)与依赖注入(DI)—IoC容器在系统中的位置
java·开发语言·spring boot·后端·spring
凡人的AI工具箱2 小时前
每天40分玩转Django:Django表单集
开发语言·数据库·后端·python·缓存·django
赖龙2 小时前
springboot restful mybatis连接mysql返回日期格式不对
spring boot·mybatis·restful
不能只会打代码2 小时前
Java并发编程框架之综合案例—— 分布式日志分析系统(七)
java·开发语言·分布式·java并发框架
自律的kkk2 小时前
SpringBoot中使用AOP切面编程实现登录拦截
java·spring boot·aop·切面编程·登录拦截
奔跑草-2 小时前
【数据库】SQL应该如何针对数据倾斜问题进行优化
数据库·后端·sql·ubuntu