阿里云使用Docker部署minio整合SpringBoot

第一步:拉取镜像

docker pull minio/minio

第二步:运行镜像

docker run \
    -p 19000:9000 \
    -p 19001:9001 \
    --name sifan-minio \
    -d --restart=always \
    -v /root/sifan/minio/data:/data \
    -e "MINIO_ROOT_USER=admin" \
    -e "MINIO_ROOT_PASSWORD=123456" \
    minio/minio:latest server /data --console-address ":9001"

第三步、开放阿里云端口19000好19001

访问控制台:http://118.31.8.23:19001/login

连接失败

看一下容器运行状况

 发现minio端口没有映射,可以是配置出问题了

看一下容器日志

docker logs sifan-minio

 发现一直报这个错误,并且容器一直会重启,启动是cpu彪增

这个错误意思是秘密最少要8个字符,而123456之后6个字符,明显不符合要求

停掉容器

docker stop sifan-minio

删除容器

docker rm -f sifan-minio

修改秘密长度重新启动镜像

docker run \
    -p 19000:9000 \
    -p 19001:9001 \
    --name sifan-minio \
    -d --restart=always \
    -v /root/sifan/minio/data:/data \
    -e "MINIO_ROOT_USER=admin" \
    -e "MINIO_ROOT_PASSWORD=12345678" \
    minio/minio:latest server /data --console-address ":9001"

这下看一下容器启动情况

 看下日志

 完美,没有报错,使用浏览器访问下看看

http://118.31.8.23:19001/login

完美,可以访问了

注意:日志里面的Console: http://172.17.0.2:9001 http://127.0.0.1:9001,是容器的端口,而启动是映射了linux操作系统的19001端口,浏览器访问19001端口时linux会通过网桥访问容器的9001端口。

使用Springboot整合minio

引入依赖,需要引入okhttp的原因是minio需要依赖okhttp4

        <!--minio-->
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>8.2.1</version>
        </dependency>
 <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.8.1</version>
            <scope>compile</scope>
        </dependency>

配置文件

minio:
  # minio配置的地址,端口19000
  url: http://118.31.8.23:19000
  # 账号
  accessKey: admin
  # 密码
  secretKey: 12345678
  # MinIO桶名字
  bucketName: sifanOS

配置类


import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@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();
    }
}

这是idea可以会提示缺少

configuration-processor

按照idea的提示引入依赖

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

打包工具排除configuration-processor



<project>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.springframework.boot</groupId>
                            <artifactId>spring-boot-configuration-processor</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

idea可能还提示要你下载big data插件,按提示下载重启即可

工具类


import com.sifan.erp.domain.ObjectItem;
import io.minio.*;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import org.springframework.stereotype.Component;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class MinioUtil {

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

实体类

@Data
public class ObjectItem {
    private String objectName;
    private Long size;
}

service层

import org.springframework.web.multipart.MultipartFile;

public interface SysFileService {
    /**
     * 文件上传*
     *
     * @param file 上传的文件
     * @return 返回的url
     */
    String uploadFileMinio(MultipartFile file);
}

serviceImpl

@Service
public class SysFileServiceInpl implements SysFileService {

    @Resource
    private MinioConfig minioConfig;

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

FileUploadUtils工具类

import java.util.Date;
import java.util.UUID;

/**
 * 文件上传工具类
 */
public class FileUploadUtils {

    /**
     * 编码文件名 如 : images/user/2020/12/4/***.png
     */
    public static final String extractFilename(MultipartFile file) {
        String fileName = file.getOriginalFilename();
        String extension = getExtension(file);
        fileName = DateFormatUtils.format(new Date(), "yyyy/MM/dd") + "/" + UUID.randomUUID().toString().replaceAll("-", "") + "." + extension;
        return fileName;
    }

    /**
     * 获取文件名的后缀
     *
     * @param file 表单文件
     * @return 后缀名
     */
    public static final String getExtension(MultipartFile file) {
        String extension = FilenameUtils.getExtension(file.getOriginalFilename());
        if (!StrUtil.isNotEmpty(extension)) {
            extension = MimeTypeUtils.getExtension(file.getContentType());
        }
        return extension;
    }

}

媒体类型工具类
/**
 * 媒体类型工具类
 */
public class MimeTypeUtils {
    public static final String IMAGE_PNG = "image/png";

    public static final String IMAGE_JPG = "image/jpg";

    public static final String IMAGE_JPEG = "image/jpeg";

    public static final String IMAGE_BMP = "image/bmp";

    public static final String IMAGE_GIF = "image/gif";

    public static final String[] IMAGE_EXTENSION = {"bmp", "gif", "jpg", "jpeg", "png"};

    public static final String[] DEFAULT_ALLOWED_EXTENSION = {"bmp", "gif", "jpg", "jpeg", "png"};

    public static String getExtension(String prefix) {
        switch (prefix) {
            case IMAGE_PNG:
                return "png";
            case IMAGE_JPG:
                return "jpg";
            case IMAGE_JPEG:
                return "jpeg";
            case IMAGE_BMP:
                return "bmp";
            case IMAGE_GIF:
                return "gif";
            default:
                return "";
        }
    }
}


控制器

@RestController
@RequestMapping("/system/file")
public class SysFileController {
    @Resource
    private SysFileService sysFileService;

    @PostMapping("/upload")
    public Result uploadFileMinio(MultipartFile file) {
        String url = sysFileService.uploadFileMinio(file);
        Result result = new Result();
        if (StrUtil.isNotEmpty(url)) {
            result.setCode(200);
            result.setMessage("上传成功");
            result.setData(url);
        } else {
            result.setMessage("上传失败");
        }
        return result;
    }
}

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值