springboot项目中使用minio进行对象存储

一、使用minio的原因

1、高性能:

minio是全球领先的对象存储先锋,在标准硬件上,读/写速度上高达183 GB / 秒 和 171 GB / 秒。

2、可扩展性:

minio利用了web缩放器的来之不易的知识,为对象存储带来了简单的存储缩放模型, 在 MinIO, 扩展从单个群集开始,该群集可以与其他MinIO群集联合以创建全局名称空间, 并在需要时可以跨越多个不同的数据中心。 通过添加更多集群可以扩展名称空间, 更多机架,直到实现目标。

3、云原生支持:

MinIO 是在过去4年的时间内从0开始打造的一款软件 ,符合一切原生云计算的架构和构建过程,并且包含最新的云计算的全新的技术和概念。 其中包括支持Kubernetes 、微服和多租户的的容器技术。使对象存储对于 Kubernetes更加友好。

4、源码开放与企业级支持:

MinIO 基于Apache V2 license 100% 开放源代码 。 这就意味着 MinIO的客户能够自动的、无限制、自由免费使用和集成MinIO、自由的创新和创造、 自由的去修改、自由的再次发行新的版本和软件. 确实, MinIO 强有力的支持和驱动了很多世界500强的企业。 此外,其部署的多样性和专业性提供了其他软件无法比拟的优势。

二、minio的下载和部署

1、Linux中minio的下载安装:

访问MinIO Quickstart Guide| Minio中文文档下载minio并部署

部署命令:./minio server /data --console-address “:9000” 解释:/data 是minio存放数据的路径,–console-address “:9000” 指定的是minio控制台启动的端口号。

注意:需要在在防火墙中开启9000端口和你指定的控制台端口,minio启动成功后默认账号密码为minioadmin

在linux中输入 ps -aux | grep minio,若出现下图所示,则启动成功,我这里控制台使用的是49000端口

启动成功后访问ip:端口号,出现以下页面则成功

三、springboot中引入minio

1、maven坐标引入

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

2、minio配置 yml文件中的配置

# Minio配置
minio:
  # minio配置的地址,端口9000
  url: http://192.168.31.2:9000
  # 账号
  accessKey: minioadmin
  # 密码
  secretKey: minioadmin
  # MinIO桶名字
  bucketName: test-bucket

3、minio使用的util

/**
 * minio存储
 *
 * @author zhifeng
 * @date  2022-05-05
 * @since 1.0.0
 */
@Component
public class MinioUtil {
    
    @Autowired
    private MinioClient minioClient;

    /**
     * 查看存储bucket是否存在
     *
     * @param bucketName 存储bucket
     * @return boolean
     */
    public Boolean bucketExists(String bucketName) {
        Boolean found;
        try {
            found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return found;
    }

    /**
     * 创建存储bucket
     *
     * @param bucketName 存储bucket名称
     * @return Boolean
     */
    public Boolean makeBucket(String bucketName) {
        try {
            minioClient.makeBucket(MakeBucketArgs.builder()
                    .bucket(bucketName)
                    .build());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 删除存储bucket
     *
     * @param bucketName 存储bucket名称
     * @return Boolean
     */
    public Boolean removeBucket(String bucketName) {
        try {
            minioClient.removeBucket(RemoveBucketArgs.builder()
                    .bucket(bucketName)
                    .build());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 文件上传
     *
     * @param file       文件
     * @param bucketName 存储bucket
     * @return Boolean
     */
    public Boolean upload(MultipartFile file, String fileName, String bucketName) {
        try {
            PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(bucketName).object(fileName)
                    .stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build();
            //文件名称相同会覆盖
            minioClient.putObject(objectArgs);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 文件下载
     *
     * @param bucketName 存储bucket名称
     * @param fileName   文件名称
     * @param res        response
     * @return Boolean
     */
    public void download(String bucketName, String fileName, HttpServletResponse res) {
        GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(bucketName)
                .object(fileName).build();
        try (GetObjectResponse response = minioClient.getObject(objectArgs)) {
            byte[] buf = new byte[1024];
            int len;
            try (FastByteArrayOutputStream os = new FastByteArrayOutputStream()) {
                while ((len = response.read(buf)) != -1) {
                    os.write(buf, 0, len);
                }
                os.flush();
                byte[] bytes = os.toByteArray();
                res.setCharacterEncoding("utf-8");
                //设置强制下载不打开
                res.setContentType("application/force-download");
                res.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
                try (ServletOutputStream stream = res.getOutputStream()) {
                    stream.write(bytes);
                    stream.flush();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 查看文件对象
     *
     * @param bucketName 存储bucket名称
     * @return 存储bucket内文件对象信息
     */
    public List<ObjectItem> listObjects(String bucketName) {
        Iterable<Result<Item>> results = minioClient.listObjects(
                ListObjectsArgs.builder().bucket(bucketName).build());
        List<ObjectItem> objectItems = new ArrayList<>();
        try {
            for (Result<Item> result : results) {
                Item item = result.get();
                ObjectItem objectItem = new ObjectItem();
                objectItem.setObjectName(item.objectName());
                objectItem.setSize(item.size());
                objectItems.add(objectItem);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return objectItems;
    }

    /**
     * 批量删除文件对象
     *
     * @param bucketName 存储bucket名称
     * @param objects    对象名称集合
     */
    public Iterable<Result<DeleteError>> removeObjects(String bucketName, List<String> objects) {
        List<DeleteObject> dos = objects.stream().map(e -> new DeleteObject(e)).collect(Collectors.toList());
        Iterable<Result<DeleteError>> results = minioClient.removeObjects(RemoveObjectsArgs.builder().bucket(bucketName).objects(dos).build());
        return results;
    }
}

4、minio使用的config配置类

@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioConfig {
    /**
     * 服务地址
     */
    public String url;

    /**
     * 用户名
     */
    public String accessKey;

    /**
     * 密码
     */
    public String secretKey;

    /**
     * 存储桶名称
     */
    public String bucketName;

    // "如果是true,则用的是https而不是http,默认值是true"
    public static Boolean secure = false;

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    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;
    }

    public static Boolean getSecure() {
        return secure;
    }

    public static void setSecure(Boolean secure) {
        MinioConfig.secure = secure;
    }

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

5、使用minio进行文件上传

controller层:

@RestController
@RequestMapping("/system/file")
public class SysFileController extends BaseController {

    @Autowired
    private ISysFileService sysFileService;

    /**
     * 图片上传minio
     *
     * @param file 图片文件
     * @return 返回
     */
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public Result uploadFileMinio(MultipartFile file) {
        String url = sysFileService.uploadFileMinio(file);
        if (StringUtils.isNotEmpty(url)) {
            return Result.success(url);
        }
        return Result.error("上传失败!");
    }

}

serviceImpl层

@Service
public class SysFileServiceImpl implements SysFileService {

    @Autowired
    private MinioConfig minioConfig;

    @Autowired
    private MinioUtil minioUtil;

    @Override
    public String uploadFileMinio(MultipartFile file) {
        boolean flag = false;
        if (file.isEmpty()) {
            throw new RuntimeException("文件不存在!");
        }
        // 判断存储桶是否存在
        if (!minioUtil.bucketExists(minioConfig.getBucketName())) {
            minioUtil.makeBucket(minioConfig.getBucketName());
        }
        // 生成文件名
        String fineName = FileUploadUtils.extractFilename(file);
        try {
            // 上传文件
            flag = minioUtil.upload(file, fineName, minioConfig.getBucketName());
        } catch (Exception e) {
            return null;
        }
        // 判断是否上传成功,成功就返回url,不成功就返回null
        if (flag){
            return minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + fineName;
        }
        return null;
    }
}

返回的url就是文件上传后的url,访问url就能看到上传的图片。

先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

猜你喜欢

转载自blog.csdn.net/m0_67391907/article/details/126115848