侧边栏壁纸
  • 累计撰写 101 篇文章
  • 累计创建 89 个标签
  • 累计收到 9 条评论

minio与springboot集成

bearjun
2021-08-11 / 1 评论 / 1 点赞 / 1,842 阅读 / 7,003 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2021-08-11,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

前面说了下minio的安装和配置,这次,我们来看看怎么和springboot进行集成使用。
首先说一下版本:
Springboot版本:2.2.5.RELEASE
minio版本:8.x
官方文档:https://docs.min.io/docs/java-client-quickstart-guide.html

依赖

添加依赖,官方给出的版本是8.3.0,但是用这个版本后会报错:
45854-njs72sk2vcq.png
然后我们将版本稍微降低下:

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

创建minioClient对象

89556-obv5di3nnf.png
由官方的文档可以看出,创建minioClient的方式有很多种。
要的参数无非就是:

  • url ip地址
  • port 端口号
  • access key 用户名
  • secret key 密码
  • bucketName 桶名称
  • userSSL 是否使用ssl

那我们首先就创建一个MinioClientProp文件,把这些参数写在配置文件中,然后通过参数注入的方式来加载参数:

@Configuration
@ConfigurationProperties("bearweb.minio")
@Slf4j
@Data
public class MinioClientProp implements InitializingBean {

    private String url;
    private Integer port;
    private String accessKey;
    private String secretKey;
    private Boolean userSSL;
    private String bucketName;

    @Bean
    public MinioClient minioClient() {

        MinioClient minioClient;
        try {
            // 创建minioClient 
            minioClient = MinioClient.builder().endpoint(url, port, userSSL).credentials(accessKey, secretKey).build();
            // 判断是否存在桶,不存在则创建桶
            boolean hasBucket = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if (!hasBucket) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new RuntimeException("minioClient初始化失败");
        }
        return minioClient;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        log.info("-------minio初始化完成---------");
    }
}

yaml中的配置文件如下:

spring:
  minio:
    url: 192.168.0.3
    port: 9002
    accessKey: 用户名
    secretKey: 密码
    userSSL: false
    bucketName: bearweb

当项目启动没有问题,就说明配置没有问题,如果启动报错,ip或者端口或者用户名密码错误,需要按照按照启动的配置填写正确后可启动正常。

封装自己常用的工具类

官方地址:https://docs.min.io/docs/java-client-api-reference.html
04998-aq07uspse4v.png
其实官方地址已经给出了操作文档和demo,我们只需要按照自己的需要封装即可:

@Component
@Slf4j
public class MinioOpsUtil {

    @Autowired
    private MinioClientProp minioClientConfig;
    @Autowired
    private MinioClient minioClient;

    public StatObjectResponse getFileInfo(String objectName, String bucketName){
        try {
            if (StringUtils.isBlank(bucketName)){
                bucketName = minioClientConfig.getBucketName();
            } else {
                throw new Exception("操作失败!桶不存在!");
            }
            return minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build());
        } catch (Exception e) {
            return null;
        }
    }

    public void download(String objectName, String bucketName, String fileName,  HttpServletResponse  response) throws Exception{
        if (StringUtils.isNotBlank(bucketName)){
            if (!this.bucketExists(bucketName)){
                throw new Exception("操作失败!桶不存在!");
            }
        } else {
            bucketName = minioClientConfig.getBucketName();
        }
        InputStream stream = minioClient.getObject(GetObjectArgs.builder()
                                        .bucket(bucketName)
                                        .object(objectName)
                                        .build());
        response.setContentType("application/force-download");
        response.setHeader("Content-Disposition", "attachment;filename="+ fileName);
        response.setCharacterEncoding("UTF-8");
        IOUtils.copy(stream, response.getOutputStream());
    }

    /**
     * 上传单个文件到指定的桶
     * @param file MultipartFile
     * @param bucketName 桶名称,如果不存在,则系统配置的桶
     * @throws Exception
     */
    public String upload(MultipartFile file, String bucketName) throws Exception{
        // 判断是否传入桶名称
        if (StringUtils.isNotBlank(bucketName)){
            if (!this.bucketExists(bucketName)){
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }
        } else {
            bucketName = minioClientConfig.getBucketName();
        }
        // 获取原始,名称
        String fileName = file.getOriginalFilename();
        // 截取新的名称
        String objectName = UUID.randomUUID().toString().replaceAll("-", "") +
                                        fileName.substring(fileName.lastIndexOf("."), fileName.length());
        // 日期前缀
        String folderPrefix = this.timeFolder();
        objectName = folderPrefix + "/" +objectName;
        // 上传
        minioClient.putObject(PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .stream(file.getInputStream(), file.getSize(), -1)
                    .contentType(file.getContentType())
                    .build());
        String url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs
                .builder().method(Method.GET).bucket(bucketName).object(objectName).build());
        // 原始路径为 ip:port/bucketName/objectName?minio自带参数
        // 截取后只保留 ip:port/bucketName/objectName
        url = url.split("\\?")[0];
        return url;
    }

    /**
     * 上传多个文件到系统配置的桶
     * @param files MultipartFile
     * @param bucketName 桶名称,如果不存在,则系统配置的桶
     * @throws Exception
     */
    public List<String> uploadBatch(MultipartFile[] files, String bucketName) throws Exception{
        // 判断是否传入桶名称
        if (StringUtils.isNotBlank(bucketName)){
            if (!this.bucketExists(bucketName)){
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }
        } else {
            bucketName = minioClientConfig.getBucketName();
        }
        String finalBucketName = bucketName;
        List<String> urlList = Collections.synchronizedList(new ArrayList<>());
        Arrays.asList(files).parallelStream().forEach(file -> {
            try {
                String filePath = this.upload(file, finalBucketName);
                urlList.add(filePath);
            } catch (Exception e) {
                log.info("文件上传失败,文件名:{}",file.getOriginalFilename());
                throw new RuntimeException("文件上传失败", e);
            }
        });
        return urlList;
    }

    /**
     * 从指定的桶删除文件
     * @param objectName 文件名称
     * @param bucketName 桶名称,如果不存在,则系统配置的桶
     * @throws Exception
     */
    public void delete(String objectName, String bucketName) throws Exception{
        // 判断是否传入桶名称
        if (StringUtils.isBlank(bucketName)){
            bucketName = minioClientConfig.getBucketName();
        } else {
            if (!this.bucketExists(bucketName)){
                throw new Exception("操作失败!桶不存在!");
            }
        }
        minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build());
    }

    /**
     * 批量从指定的桶删除文件
     * @param objectNames 文件名称
     * @param bucketName 桶名称,如果不存在,则系统配置的桶
     * @throws Exception
     */
    public void deleteBatch(String[] objectNames, String bucketName) throws Exception{
        // 判断是否传入桶名称
        if (StringUtils.isBlank(bucketName)){
            bucketName = minioClientConfig.getBucketName();
        } else {
            if (!this.bucketExists(bucketName)){
                throw new Exception("操作失败!桶不存在!");
            }
        }
        String finalBucketName = bucketName;
        Arrays.stream(objectNames).parallel().forEach(objectName ->{
            try {
                minioClient.removeObject(RemoveObjectArgs.builder().bucket(finalBucketName).object(objectName).build());
            } catch (Exception e) {
                log.info("文件删除失败,文件名:{}", objectName);
                throw new RuntimeException("文件上传失败", e);
            }
        });
    }

    /**
     * 获取当前时间转换成字符串
     * @return
     */
    private String timeFolder(){
        LocalDate time = LocalDate.now();
        String format = time.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        return format;
    }

    /**
     * 判断是否存在传入的桶,不存在创建
     * @param bucketName
     * @throws IOException
     * @throws InvalidKeyException
     * @throws InvalidResponseException
     * @throws InsufficientDataException
     * @throws NoSuchAlgorithmException
     * @throws ServerException
     * @throws InternalException
     * @throws XmlParserException
     * @throws ErrorResponseException
     */
    private Boolean bucketExists(String bucketName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException,
                                        NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
        boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        return found;
    }
}

测试

首先控制台是没有今天的数据的:
30906-nd6xwgzrhmr.png
首先是文件的上传,由于我们没有指定桶,默认上传到系统配置文件配置的桶里面:

@Autowired
    private MinioOpsUtil minioOpsUtil;

@PostMapping("/uploadUserPicture")
    public CommonResult uploadUserPicture(@RequestParam("file") MultipartFile file) throws Exception {
        String filePath = minioOpsUtil.upload(file, null);
        return CommonResult.success(filePath);
    }

04269-54llfcsvi7j.png
这个就是刚才上传的文件:
00243-mab9fhx1w1o.png
其他我也不演示了,应该没啥问题。

小弟我也是第一次接触minio,如有纰漏,欢迎各位大佬指出。

1

评论区