Spring Boot 中上传文件到 Minio

一、需求背景

在写苍穹外卖这个项目时需要alioss上传,没有自己的oss,发现了Minio这个项目,本着有点编程经验,折腾一下,也能让自己理解的更加深刻😀

二、项目介绍

1、Minio
    开源分布式存储方案(Goland编写), 本文只是单机部署一下,替代oss方案
2、苍穹外卖
    无需多言,黑马出品,项目组人数众多😀

三、项目配置

1、除java主程序在windows外, mysql,redis,Minio、等都是在wsl2里通过原生docker启动

tips:随便找个dnpm的 docker-compose改改就行

version: "3"
services:
  mysql:
    image: mysql:${MYSQL_VERSION}
    container_name: mysql
    volumes:
      - ${MYSQL_DATA}:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
      TZ: "$TZ"
    ports:
      - ${MYSQL_PORT}:3306

  redis:
    image: redis:${REDIS_VERSION}
    container_name: redis
    restart: always
    volumes:
      - ${REDIS_DATA}:/data
      - ${REDIS_CONF}:/usr/local/etc/redis/redis.conf
    ports:
      - ${REDIS_PORT}:6379
    command: [ redis-server, "/usr/local/etc/redis/redis.conf" ]

  minio:
    image: minio/minio
    hostname: "minio"
    ports:
      - 9000:9000 # api 端口
      - 9001:9001 # 控制台端口
    environment:
      MINIO_ACCESS_KEY: admin     #管理后台用户名
      MINIO_SECRET_KEY: admin123 #管理后台密码,最小8个字符
    volumes:
      - /docker/minio/data:/data               #映射当前目录下的data目录至容器内/data目录
      - /docker/minio/config:/root/.minio/     #映射配置目录
    command: server --console-address ':9001' /data  #指定容器中的目录 /data
    privileged: true
    restart: always

2、引入maven坐标

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

3、docker-composer 镜像运行后配置Minio

①进入后台管理界面并登录

Spring Boot 中上传文件到 Minio

②创建桶

Spring Boot 中上传文件到 Minio

③配置桶权限及创建密钥

Spring Boot 中上传文件到 Minio

创建密钥并记录保存密钥

Spring Boot 中上传文件到 Minio

四、代码实现

1、创建Minio配置对象类

package com.sky.properties;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "sky.minio")
@Data
public class MinioProperties {
    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    private String bucketName;
}

2、配置application-dev.yml

sky:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    host: localhost
    port: 3306
    database: sky_take_out
    username: root
    password: root
    #增加Minio配置
  minio:
    # API 端点
    endpoint: "http://127.0.0.1:9000/"
    # 上传的 Bucket
    bucket-name: sky-take-out
    # Access Key
    access-key-id: *****
    # Secret Key
    access-key-secret: *****

3、创建Minio工具类

package com.sky.utils;

import io.minio.errors.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;


@Data
@AllArgsConstructor
@Slf4j
public class MinioUtil {

    private String endpoint;
    private String accessKey;
    private String secretKey;
    private String bucketName;

    public String upload(MultipartFile file, String objectName) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        // 实例化客户端
        MinioClient client = MinioClient.builder()
                .endpoint(this.endpoint)
                .credentials(this.accessKey, this.secretKey)
                .build();

        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
        client.putObject(PutObjectArgs.builder()
                .bucket(this.bucketName)
                .object(objectName)
                .stream(inputStream, file.getSize(), -1)
                .contentType(file.getContentType())
                .build());

        return this.endpoint + this.bucketName + "/" + objectName;
    }

}

4、创建公用的控制器并注入MinioUtil实例

package com.sky.controller.admin;

import com.sky.result.Result;
import com.sky.utils.MinioUtil;
import io.minio.errors.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

/**
 *  通用接口
 */

@RequestMapping("/admin/common")
@RestController
@Api(tags = "通用接口")
@Slf4j
public class CommonController {
    @Autowired
    private MinioUtil minioUtil;
    /**
     * 文件上传
     * @param file
     * @return
     */
    @ApiOperation("文件上传接口")
    @PostMapping("/upload")
    public Result<String> upload(MultipartFile file) {
        log.info("文件上传 : {}", file);
        String originalFilename = file.getOriginalFilename();
        String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
        String objectName = UUID.randomUUID() + extension;
        String filePath = null;
        try {
            filePath = minioUtil.upload(file, objectName);
            return Result.success(filePath);
        } catch (Exception e) {
            log.error("文件上传失败: {}", e);
            return Result.error("文件上传失败");
        }
    }
}

五、结果展示

Spring Boot 中上传文件到 Minio

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!