Java使用Minio实现图片上传

最近项目中使用Minio图床服务器实现图片上传,在此做一个记录,项目中的环境如下:
Nacos、Gradle、springBoot、mybatis、MySQL…

首先,需要在Gradle中添加Minio的依赖,此项目中使用的是3.0.10版本

compile 'io.minio:minio:3.0.10'

然后在项目中添加MinioUtils的配置类,旨在调用Minio的服务,提供调用Minio上传图片的接口,项目中所需参数都写在了Nacos配置中心,因此使用@NacosValue的注解形式从Nacos配置文件中拿取对应的参数,调用上传图片的接口,返回一个 Minio域名/桶名/存入桶中的文件名 的url

import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.iid.common.helper.IdHelper;
import io.minio.MinioClient;
import io.minio.errors.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.xmlpull.v1.XmlPullParserException;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * @ClassName MinioUtils
 * @Description: TODO
 * @Author XuJianSong
 * @Date 2021-01-07
 * @Version V1.0
 **/
@Slf4j
@Component
public class MinioUtils {
    private MinioClient minioClient;
    @NacosValue(value = "${ymukj.minio.endpoint}")
    private String endPoint;//Minio的域名
    @NacosValue(value = "${ymukj.minio.accessKey}")
    private String accessKey;//Minio登录名
    @NacosValue(value = "${ymukj.minio.secretKey}")
    private String secretKey;//Minio登陆密码
    @NacosValue(value = "${ymukj.minio.preUrl}")
    private String preUrl;//图床图片的域名(带bucket的)

    @PostConstruct
    public void initMinioClient() {//调用Minio服务
        try {
            minioClient = new MinioClient(endPoint, accessKey, secretKey);
        } catch (InvalidEndpointException e) {
            log.error(e.getMessage(), e);
        } catch (InvalidPortException e) {
            log.error(e.getMessage(), e);
        }
    }

    public String uploadFile(String bucketName, String objName, InputStream inputStream, Long lenght, String contentType) {
        // 使用putObject上传一个文件到存储桶中。
        try {
            minioClient.putObject(bucketName, objName, inputStream, lenght, contentType);
            boolean isExist = minioClient.bucketExists(bucketName);
            if (!isExist) {
                minioClient.makeBucket(bucketName);
            }
            return preUrl+"/"+objName;
        } catch (Exception e) {
            e.printStackTrace();
            log.info(">>>>>>>>>>>>>>>>>>>>>>>>>Error:" + e);
            return null;
        }
    }
}

在Minio中是有“桶(bucket)”的概念的,所谓的桶,就是在Minio的图床上的文件夹,如果传参的桶名称在图床上已存在,上传的图片就会存入当前桶中;
如果传参的桶名称在图床上不存在,源码方法中会先创建桶,再存入

在这里插入图片描述

如图所示:左边的就是Minio图床中的桶,右边就是桶中的文件,Minio是支持上传所有文件的,视频、文档文件都可以,不过项目中没有涉及到这些功能,待后续再研究

接下来就是在项目中写上传图片的接口了,因为不涉及的数据库的操作,所以我直接在controller层中把接口全部写完了,没有再去调用service层的方法
Controller层接口接收前端的文件传参,再根据MinioUtils配置类中,上传图片的方法接收参数的要求,对文件进行处理,首先我们能看到MinioUtils配置文件中的上传图片接口要求接收的参数是bucket, objName, inputStream, lenght, contentType这四个,这四个参数分别是:桶名、上传并保存到桶的文件名,文件的输入流,文件的类型。上传成功的话会返回一个url,将这个url放到浏览器中可以直接打开这个图片,项目中如果需要使用这张图片,可以直接将这个url存入到数据库中,后面可以从数据库中直接取用

public GlobalResponse uploadPic(MultipartFile file) {
    String bucket = "pic";
    String filename = file.getOriginalFilename();
    String[] exts = filename.split("\\.");
    String ext = exts[exts.length - 1];
    String caselsh = filename.substring(0,filename.lastIndexOf("."));
    String objName = SystemHelper.now() + caselsh + "." + ext;
    log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>objName:" + objName);
    String contentType = file.getContentType();
    InputStream inputStream = null;
    Long lenght = null;
    try {
        inputStream = file.getInputStream();
        lenght = Long.valueOf(inputStream.available());
    } catch (IOException e) {
        e.printStackTrace();
    }
    String picUrl = minioUtils.uploadFile(bucket, objName, inputStream, lenght, contentType);
    log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>picUrl:" + picUrl);
    return GlobalResponse.success(picUrl);
}

这里需要注意的是上传到桶的文件名不要重复!不要重复!不要重复!
因为重复的文件名会导致一个问题:比如先上传一个图片A.png,存到桶中的名称是111.png,那么Minio域名/桶名/111.png就能直接打开文件A.png这张图,但是再上传一个图片B.png,存到同种的名称仍然是111.png,那么Minio域名/桶名/111.png打开的就是B.png这张图,如果图片A.png已经存入数据库,并已经使用的话,后果可想而知。
因此接口中使用的解决方案是,使用时间戳+文件原名称+后缀的形式来命名,因为时间戳是13位毫秒级的,因此就算是上传同名的文件,也不会有存到桶中的文件名会重复的问题

本次的分享就到这里,如有错误欢迎大家来指正!

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用MinIO Java客户端来实现文件上传和下载。MinIO是一个基于对象存储的开源项目,可以提供高性能的文件存储和访问。 首先,你需要在你的Java项目中添加MinIO Java客户端的依赖。你可以在Maven或者Gradle配置文件中加入以下依赖: Maven: ```xml <dependencies> <dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>8.1.0</version> </dependency> </dependencies> ``` Gradle: ```groovy dependencies { implementation 'io.minio:minio:8.1.0' } ``` 接下来,你需要连接到MinIO服务器并进行认证。你可以使用以下代码完成: ```java import io.minio.MinioClient; public class MinioExample { public static void main(String[] args) { try { // 创建MinIO客户端对象 MinioClient minioClient = new MinioClient("http://your-minio-server-url", "access-key", "secret-key"); // 检查存储桶是否存在,如果不存在则创建 boolean isExist = minioClient.bucketExists("your-bucket"); if (!isExist) { minioClient.makeBucket("your-bucket"); } // 上传文件 minioClient.putObject("your-bucket", "your-object-name", "/path/to/your-file"); // 下载文件 minioClient.getObject("your-bucket", "your-object-name", "/path/to/save-file"); } catch (Exception e) { e.printStackTrace(); } } } ``` 在上面的代码中,你需要替换以下参数: - `your-minio-server-url`:MinIO服务器的URL地址。 - `access-key`:你的MinIO访问密钥。 - `secret-key`:你的MinIO密钥。 - `your-bucket`:存储桶的名称。 - `your-object-name`:对象的名称。 - `/path/to/your-file`:待上传的文件路径。 - `/path/to/save-file`:下载文件保存的路径。 通过上述代码,你可以使用MinIO Java客户端实现文件上传和下载。希望对你有帮助!如有任何问题,请随时提出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值