SpringBoot引入MinIO实现图片文件上传,下载(三)

本章内容:Springboot2.0引入MinIO实现文件的上传和下载功能,以及引入过程中遇到的Bug;

Docker 快速部署 MinIo

引入依赖配置

pom.xml中引入MinIO依赖

<!-- 引入 minio  start-->
<dependency>
	<groupId>io.minio</groupId>
	<artifactId>minio</artifactId>
	<version>8.3.1</version>
	<exclusions>
    <!-- 移除 依赖的低版本包 -->
		<exclusion>
			<groupId>com.squareup.okhttp3</groupId>
			<artifactId>okhttp</artifactId>
		</exclusion>
	</exclusions>
</dependency>

<!-- https://mvnrepository.com/artifact/org.web3j/core -->
<dependency>
	<groupId>com.squareup.okhttp3</groupId>
	<artifactId>okhttp</artifactId>
	<version>4.8.1</version>
</dependency>
<!-- 引入 minio  end-->

application.yml中配置MinIO

server:
  port: 6001
min:
  io:
    secure: false
    endpoint: http://127.0.0.1:9000
    point: 80
    accessKey: FASDFFSFDG7EXASDFAD
    secretKey: eJalrSDtnFEMI/ASDF3GSD/bPxRfiCYEXASDFADEY

核心编码

MinIO 属性配置文件以及将MinIO注入到spring管理

package net.sm.util.minio;

import io.minio.MinioClient;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Author GGYYJJ
 * @Date 2021/10/13 10:45
 * @Version 1.0
 * @Title
 * @Desc
 */
@Configuration
@Data
public class MinIoConfig {
    /**
     * Minio 服务地址
     */
    @Value("${min.io.endpoint}")
    private String endpoint;

    /**
     * Minio 服务端口号
     */
    @Value("${min.io.point}")
    private Integer point;

    /**
     * Minio ACCESS_KEY
     */
    @Value("${min.io.accessKey}")
    private String accessKey;

    /**
     * Minio SECRET_KEY
     */
    @Value("${min.io.secretKey}")
    private String secretKey;

    /**
     * Minio 是否为https 请求,true 地址为http,false地址为http
     */
    @Value("${min.io.secure}")
    private boolean secure;

    @Bean
    public MinioClient minioClient(){
        return MinioClient.builder()
                .endpoint(endpoint, point, secure)
                .credentials(accessKey, secretKey)
                .build();
    }

}

minio工具类,列出了常用文件操作,详细API需求请参考官方文档:

官网以及API  |  中文API

package net.sm.util.minio;

import com.alibaba.fastjson.JSONObject;
import io.minio.*;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import jodd.io.FastByteArrayOutputStream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

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

/**
 * @Author GGYYJJ
 * @Date 2021/10/12 13:28
 * @Version 1.0
 * @Title
 * @Desc
 */
@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 bucketName) {
        try {
            PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(bucketName).object(file.getOriginalFilename())
                    .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<JSONObject> listObjects(String bucketName) {
        Iterable<Result<Item>> results = minioClient.listObjects(
                ListObjectsArgs.builder().bucket(bucketName).build());
        List<JSONObject> objectItems = new ArrayList<>();
        try {
            for (Result<Item> result : results) {
                Item item = result.get();
                JSONObject objectItem = new JSONObject();
                objectItem.put("object_name",item.objectName());
                objectItem.put("size",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;
    }
}

测试

controller控制器入口方法,上传完之后可以在管理后台查看到。

package net.sm.controller;

import com.alibaba.fastjson.JSONObject;
import net.sm.util.minio.MinIoUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author GGYYJJ
 * @Date 2021/9/29 17:48
 * @Version 1.0
 * @Title
 * @Desc
 */
@RestController
@RequestMapping("/api/commodity/v1/")
public class CommodityController extends BaseController{

    @Autowired
    private MinIoUtil minIoUtil;

    @RequestMapping("/uploadFile")
    public void upload(@RequestParam("file") MultipartFile file) throws Exception {
        System.out.println(minIoUtil.upload(file, "my-bucketname"));

    }

    /**
     * minio下载文件
     */
    @GetMapping("/download")
    public void download(HttpServletResponse res){
        minIoUtil.download("my-bucketname","logo.png", res);
    }

}

PostMan测试图片上传

 登录MinIO管理后台,找到对应的bucket下就可以看到上传成功的图片;

文件下载,打开浏览访问地址,http://127.0.0.1:6001/api/commodity/v1/download ,后台返回的文件流在浏览器进行下载;

 过程中遇到的问题:

1、在引入MinIo的时候,MinIO里面依赖的okhttp去除掉,并重新引入高版本的okhttp包。否则会报错;

okhttp3.RequestBody: file:/D:/Work20170505/mavn-repository/com/squareup/okhttp3/okhttp/3.14.9/okhttp-3.14.9.jar

Correct the classpath of your application so that it contains a single, compatible version of okhttp3.RequestBody
2、在Maven项目编译过程中,如果遇上缺少依赖,或是已引入依赖还报错的,在项目根目录执行mvn clean install;idea 要开启pom自动导入更新jar功能;

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
首先,需要引入minio的依赖: ``` <dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>8.0.2</version> </dependency> ``` 然后,在application.properties中配置minio的连接信息: ``` minio.url=http://localhost:9000 minio.accessKey=minioadmin minio.secretKey=minioadmin minio.bucketName=test ``` 接着,创建一个MinioService类,用于处理文件上传下载: ``` @Service public class MinioService { @Value("${minio.url}") private String minioUrl; @Value("${minio.accessKey}") private String accessKey; @Value("${minio.secretKey}") private String secretKey; @Value("${minio.bucketName}") private String bucketName; private final MinioClient minioClient = new MinioClient(minioUrl, accessKey, secretKey); public void upload(MultipartFile file) throws Exception { // 生成文件名 String originalFilename = file.getOriginalFilename(); String fileName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf(".")); // 上传文件 minioClient.putObject(PutObjectArgs.builder() .bucket(bucketName) .object(fileName) .stream(file.getInputStream(), file.getSize(), -1) .contentType(file.getContentType()) .build()); } public InputStream download(String fileName) throws Exception { // 下载文件 return minioClient.getObject(GetObjectArgs.builder() .bucket(bucketName) .object(fileName) .build()); } } ``` 最后,在Controller中使用MinioService处理上传和下载请求: ``` @RestController public class MinioController { @Autowired private MinioService minioService; @PostMapping("/upload") public String upload(@RequestParam("file") MultipartFile[] files) { try { for (MultipartFile file : files) { minioService.upload(file); } return "上传成功"; } catch (Exception e) { e.printStackTrace(); return "上传失败"; } } @GetMapping("/download") public ResponseEntity<InputStreamResource> download(@RequestParam("fileName") String fileName) { try { InputStream inputStream = minioService.download(fileName); InputStreamResource inputStreamResource = new InputStreamResource(inputStream); HttpHeaders headers = new HttpHeaders(); headers.add("Content-Disposition", "attachment; filename=" + fileName); return ResponseEntity.ok().headers(headers).contentLength(inputStream.available()) .contentType(MediaType.parseMediaType("application/octet-stream")).body(inputStreamResource); } catch (Exception e) { e.printStackTrace(); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); } } } ``` 这样,就可以使用Spring BootMinio实现多文件批量上传了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

♂老码♂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值