Minio与springboot在Windows系统上部署及应用

一、minio环境部署

1.下载minio

	官网下载地址:https://min.io/download

2.安装minio

	1.下载之后,得到minio.exe文件
	2.建立文件夹,用于存放minio的文件数据(我自己设的data文件夹)

在这里插入图片描述

3.运行minio

	1.运行minio服务:E:\Minio\package minio.exe server E:\Minio\data
	2.具体路径根据自设的文件夹路径定

在这里插入图片描述

二、整合springboot

1.配置maven环境

	在pom.xml里写入minio的依赖
    <dependency>
      <groupId>io.minio</groupId>
         <artifactId>minio</artifactId>
         <version>${minio.version}</version>
     </dependency>
    <properties>
        <minio.version>8.3.5</minio.version>
    </properties>

2.配置yml文件

	在application.yml中添加下列配置
minio:
  # 服务器访问地址
  endpoint: http://10.40.16.214:9000
  #用户名
  accessKey: minioadmin
  # 密码
  secretKey: minioadmin
  # 默认桶名
  bucketName: hirain

3.注入minio客户端

	注入minio客户端
import io.minio.MinioClient;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Data
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioConfig {
    private String endpoint;
    private String accessKey;
    private String secretKey;

    /**
     * 注入minio客户端
     * @return
     */
    @Bean
    public MinioClient minioClient()  {
        return MinioClient.builder()
                          .endpoint(endpoint)
                          .credentials(accessKey, secretKey)
                          .build();
    }
}

4.写minio工具类

	写minio工具类
import com.hirain.common.entity.ResourceMessage;
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Encoder;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


@Component
@Slf4j
public class MinioUtils {

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

    @Autowired
    private MinioClient minioClient;

    /**
     * 上传文件
     */
    public String upload(String objectName, MultipartFile file) {
        try (InputStream in = file.getInputStream()) {
            PutObjectArgs objectArgs = PutObjectArgs.builder()
                                                    .bucket(bucketName)
                                                    .object(objectName)
                                                    .stream(in, in.available(), -1)
                                                    .contentType(file.getContentType())
                                                    .build();
            minioClient.putObject(objectArgs);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bucketName + File.separator + objectName;
    }

    /**
     * 通过文件名称下载文件
     */
    public boolean download(String objectName, HttpServletResponse res, HttpServletRequest req) throws Exception {
        GetObjectArgs objectArgs = GetObjectArgs.builder()
                                                .bucket(bucketName)
                                                .object(objectName)
                                                .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.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
                // filenameEncoding 方法兼容不同浏览器编码
                res.addHeader("Content-Disposition", "attachment;fileName=" + filenameEncoding(objectName, req));
                try (ServletOutputStream stream = res.getOutputStream()) {
                    stream.write(bytes);
                    stream.flush();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 设置不同浏览器编码
     */
    public static String filenameEncoding(String filename, HttpServletRequest request) throws UnsupportedEncodingException {
        // 获得请求头中的User-Agent
        String agent = request.getHeader("User-Agent");
        // 根据不同的客户端进行不同的编码
        if (agent.contains("MSIE")) {
            // IE浏览器
            filename = URLEncoder.encode(filename, "utf-8");
        } else if (agent.contains("Firefox")) {
            // 火狐浏览器
            BASE64Encoder base64Encoder = new BASE64Encoder();
            filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes(StandardCharsets.UTF_8)) + "?=";
        } else {
            // 其它浏览器
            filename = URLEncoder.encode(filename, "utf-8");
        }
        return filename;
    }

    /**
     * 删除单个文件对象
     */
    public boolean removeObject(String objectName) {
        try {
            minioClient.removeObject(RemoveObjectArgs.builder()
                                                     .bucket(bucketName)
                                                     .object(objectName)
                                                     .build());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 删除文件夹及其下所有文件对象
     */
    public boolean removeFolder(String objectName) {
        try {
            Iterable<Result<Item>> list = listObjects(objectName);
            for (Result<Item> item : list) {
                String itemName = item.get().objectName();
                removeObject(itemName);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 批量删除文件对象
     */
    public Iterable<Result<DeleteError>> removeObjects(List<String> objects) {
        return minioClient.removeObjects(RemoveObjectsArgs.builder()
                                                          .bucket(bucketName)
                                                          .objects(objects.stream()
                                                                          .map(DeleteObject::new)
                                                                          .collect(Collectors.toList()))
                                                          .build());
    }

    /**
     * 查看指定文件夹下所有文件
     */
    public List<ResourceMessage> listFolderObjects(String objectName) {
        Iterable<Result<Item>> results = listObjects(objectName);
        List<ResourceMessage> objectNameList = new ArrayList<>();
        try {
            for (Result<Item> result : results) {
                String path = bucketName + '/' + result.get().objectName();
                String url = getObjectUrl(result.get().objectName());
                objectNameList.add(new ResourceMessage(path, url));
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return objectNameList;
    }

    /**
     * 查看文件对象
     */
    public Iterable<Result<Item>> listObjects(String objectNames) {
        return minioClient.listObjects(ListObjectsArgs.builder()
                                                      .bucket(bucketName)
                                                      .prefix(objectNames)
                                                      .recursive(true)
                                                      .build());
    }

    /**
     * 获得文件外链,失效时间默认是7天
     */
    public String getObjectUrl(String objectName){
        GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder()
                                                                  .bucket(bucketName)
                                                                  .object(objectName)
                                                                  .method(Method.GET).build();
        String presignedObjectUrl = null;
        try {
            presignedObjectUrl = minioClient.getPresignedObjectUrl(args);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return presignedObjectUrl;
    }

    /**
     * 判断文件夹是否存在
     */
    public boolean isFolderExist(String objectName) {
        boolean exist = false;
        Iterable<Result<Item>> results = listObjects(objectName);
        try {
            for (Result<Item> result : results) {
                Item item = result.get();
                if (item.isDir() && objectName.equals(item.objectName())) {
                    exist = true;
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return exist;
    }

    /**
     * 判断bucket是否存在,不存在则创建
     */
    public void existBucket(String name) {
        try {
            boolean exists = minioClient.bucketExists(BucketExistsArgs.builder()
                                                                      .bucket(name)
                                                                      .build());
            if (!exists) {
                minioClient.makeBucket(MakeBucketArgs.builder()
                                                     .bucket(name)
                                                     .build());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

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

    /**
     * 获取全部bucket
     */
    public List<Bucket> getAllBuckets() {
        try {
            return minioClient.listBuckets();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}

三、测试效果

1.写controller接口

	实现文件的上传,下载,删除,预览功能

import com.hirain.common.annotation.LogOperation;
import com.hirain.common.utils.Result;
import com.hirain.common.entity.ResourceMessage;
import com.hirain.common.minio.MinioUtils;
import com.hirain.constant.MinioPrefix;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;


@Api(value = "文件云处理", tags = {"文件云处理"})
@RestController
@RequestMapping("/craftFile")
public class OssCraftController {

    @Autowired
    private MinioUtils minioUtil;

    private final String category = MinioPrefix.CRAFT;

    @PostMapping("/upload")
    @ApiOperation("上传文件资源")
    @LogOperation("上传文件资源")
    public Result<String> uploadResources(@RequestParam("craftId") Long craftId, @RequestParam("stepId") Long stepId, @RequestParam("file") MultipartFile file) {
        String originalFilename = file.getOriginalFilename();
        if (StringUtils.isNotBlank(originalFilename)) {
            String filename = originalFilename.substring(0, originalFilename.lastIndexOf("."));
            String objectName = getFilePath(craftId, stepId, filename);
            String upload = minioUtil.upload(objectName, file);
            return new Result<String>().ok(upload);
        } else {
            return new Result<String>().error();
        }
    }

    @DeleteMapping("delete/folder")
    @ApiOperation("删除文件夹")
    @LogOperation("删除文件夹")
    public Result<Boolean> deleteResources(@RequestParam("craftId") Long craftId, @RequestParam("stepId") Long stepId) {
        String folderPath = getFolderPath(craftId, stepId);
        boolean result = minioUtil.removeFolder(folderPath);
        return new Result<Boolean>().ok(result);
    }

    @DeleteMapping("delete/file")
    @ApiOperation("删除单个文件")
    @LogOperation("删除单个文件")
    public Result<Boolean> deleteResources(@RequestParam("craftId") Long craftId, @RequestParam("stepId") Long stepId, @RequestParam("filename") String filename) {
        String objectName = getFilePath(craftId, stepId, filename);
        boolean result = minioUtil.removeObject(objectName);
        return new Result<Boolean>().ok(result);
    }

    @GetMapping("download")
    @ApiOperation("下载文件")
    public Result<Boolean> download(@RequestParam("craftId") Long craftId, @RequestParam("stepId") Long stepId, @RequestParam("filename") String filename, HttpServletResponse res, HttpServletRequest req) throws Exception {
        String objectName = getFilePath(craftId, stepId, filename);
        boolean download = minioUtil.download(objectName, res, req);
        return new Result<Boolean>().ok(download);
    }

    @GetMapping("/preview")
    @ApiOperation("预览文件")
    @LogOperation("预览文件")
    public Result<String> getObjectUrl(@RequestParam("craftId") Long craftId, @RequestParam("stepId") Long stepId, @RequestParam("filename") String filename) {
        String objectName = getFilePath(craftId, stepId, filename);
        String url = minioUtil.getObjectUrl(objectName);
        return new Result<String>().ok(url);
    }

    @PostMapping("/listObjects")
    @ApiOperation("查询指定文件夹下,文件信息")
    @LogOperation("查询指定文件夹下,文件信息")
    public Result<Object> listObjects(@RequestParam("craftId") Long craftId, @RequestParam("stepId") Long stepId) {
        String folderPath = getFolderPath(craftId, stepId);
        List<ResourceMessage> objectNameList = minioUtil.listFolderObjects(folderPath);
        return new Result<>().ok(objectNameList);
    }

    @PostMapping("/listAllObjects")
    @ApiOperation("查询全部资源信息")
    @LogOperation("查询全部资源信息")
    public Result<Object> listAllObjects() {
        String folderPath = "/";
        List<ResourceMessage> objectNameList = minioUtil.listFolderObjects(folderPath);
        return new Result<>().ok(objectNameList);
    }

    @PostMapping("/isFolderExist")
    @ApiOperation("是否存在文件夹")
    @LogOperation("是否存在文件夹")
    public Result<Boolean> isFolderExist(@RequestParam("craftId") Long craftId, @RequestParam("stepId") Long stepId) {
        String folderPath = getFolderPath(craftId, stepId);
        boolean folderExist = minioUtil.isFolderExist(folderPath);
        return new Result<Boolean>().ok(folderExist);
    }


    /**
     * 得到minio中文件所在位置
     */
    public String getFilePath(Long craftId, Long stepId, String fileName) {
        return category + "/" + craftId + "/" + stepId + "/" + fileName;
    }

    /**
     * 得到minio中文件夹所在位置
     */
    public String getFolderPath(Long craftId, Long stepId) {
        return category + "/" + craftId + "/" + stepId + "/";
    }
}

2.查看minio云平台

	1.登录网址 :http://127.0.0.1:9000
	2.输入用户名minioadmin,密码minioadmin
	3.可在此处对文件进行图形化界面管理

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值