发布时间:2025-06-24 18:56:28  作者:北方职教升学中心  阅读量:594


.stream(file.getInputStream(), file.getSize(), -1):设置文件的输入流、           MinioClient minioClient = MinioClient.builder().endpoint(MinIOConfig.MINIO_END_POINT).credentials(MinIOConfig.MINIO_ACCESS_KEY, MinIOConfig.MINIO_SECRET_KEY).build();​           String dateStr = format.format(new Date());           //创建文件路径           String fileUrl = fileName+"/"+(dateStr + "/" + UUID.randomUUID().toString().replace("-","") + "_" + filename);           InputStream inputStream=in;           if(size>5*1024*1024){               //大于5M就压缩               if(filename.contains("jpg")||filename.contains("png")){                   //如果是图片,压缩一下                   inputStream = ImageUtil.compressImg(in, 1.1f);               }           }           // 上传网络流。file.getInputStream()获取文件的输入流,file.getSize()获取文件的大小,-1表示使用默认的超时时间。

1.在Linux中通过docker中拉取minio镜像

docker pull bitnami/minio 

可以使用docker images 查看是否有minio镜像,如果有说明已经获取minio镜像了

2.创建一个文件用于存储MinIO的数据

mkdir -p /minio/data

给该文件赋予完全开放的权限

chmod -R 777 minio/data

3.启动及配置 MinIo

docker run -it -d --name minio -p 9000:9000 -p 9001:9001 -v /minio/data:/data -e MINIO_ROOT_USER="minio_root" -e MINIO_ROOT_PASSWORD="minio_123456" bitnami/minio:latest

4.通过日志查看MinIo

docker logs -f minio

5.在window中访问图中的url,切记,切记浏览器访问端口9001,java API端口是9000

访问的url为 虚拟机的ip地址:9001

6.创建自己的Buckets

7.设置Buckets权限为public

8.生成密钥

导入MinIO依赖

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

配置yml文件

minio:  endpoint: http://xxx:9000 #Minio服务所在地址  bucketName: test-minio #存储桶名称  accessKey: minio_root #访问的key,也可以是上面创建的AccessKey  secretKey: minio_123456 #访问的秘钥,也可以是上面创建的SecretKey  upload: test #文件上传路径

MinIOConfig配置类

@Configurationpublic class MinIOConfig  implements InitializingBean {​    @Value("${minio.endpoint}")    private String minio_endpoint;    @Value("${minio.accessKey}")    private String minio_accessKey;    @Value("${minio.secretKey}")    private String minio_secretKey;    @Value("${minio.bucketName}")    private String minio_bucketName;    @Value("${minio.upload}")    private String minio_upload;​    public static String MINIO_END_POINT;    public static String MINIO_ACCESS_KEY;    public static String MINIO_SECRET_KEY;    public static String MINIO_BUCKET_NAME;    public static String MINIO_UPLOAD;​    @Override    public void afterPropertiesSet() throws Exception {        MINIO_END_POINT = minio_endpoint;        MINIO_ACCESS_KEY = minio_accessKey;        MINIO_SECRET_KEY = minio_secretKey;        MINIO_BUCKET_NAME = minio_bucketName;        MINIO_UPLOAD=minio_upload;    }}

文件上传的controller层:

@Autowiredprivate FileStrategy fileStrategy;​@PostMapping("upload")@ApiOperation(value = "文件上传")public Result<Url> upload(MultipartFile file) throws Exception{    Result result=new Result();    try {        log.info("upload-------------------------------");        if(null != file){            if(file.getOriginalFilename().contains("mp4")){                //如果上传的视频,校验大小不能超过2M                if(file.getSize()>2048*1024){                    result= new Result(CoReturnFormat.MP4_FILE_NOT_2M);                    return result;                }            }            String url=fileStrategy.upload(file);            //fileUploadService.uploadFile(file.getOriginalFilename(),file.getInputStream(),file.getSize());            result=new Result(new Url(url),CoReturnFormat.SUCCESS);        }        return result;    } catch (Exception e) {        log.error("upload fail " + e.getMessage(), e);    }    return result;}

FileStrategy:

public interface FileStrategy {    String upload(MultipartFile file) throws Exception;}

MinIOAutoConfigure:

@Configuration@Slf4j@ConditionalOnProperty(name = "upload.type", havingValue = "MIN")public class MinIOAutoConfigure {    @Service    public class MinIOServiceImpl implements FileStrategy{        private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");        @Override        public String upload(MultipartFile file) throws Exception {            String filename = file.getOriginalFilename();            InputStream in = file.getInputStream();            long size = file.getSize();            log.info("filename {} size {}", filename, size);            Objects.requireNonNull(filename);            filename = filename.replaceAll(" ", "");            String fileName= MinIOConfig.MINIO_UPLOAD;            // 创建MinioClient实例。

.contentType(file.getContentType()):设置文件的内容类型

运行项目报错:

Caused by: java.lang.RuntimeException: Unsupported OkHttp library found. Must use okhttp >= 4.8.1    at io.minio.S3Base.<clinit>(S3Base.java:106)    ... 50 common frames omittedCaused by: java.lang.NoSuchMethodError: kotlin.collections.ArraysKt.copyInto([B[BIII).............

问题需要将okhttp升级4.8.1以上版本

将okhttp升级到4.8.1版本后,还是不行,这时候就要思考是不是okhttp的版本冲突导致,可以通过下载Maven help插件看依赖树,我们可以注意到了报错信息中的NoSuchMethodError: kotlin.collections.ArraysKt.copyInto通过搜索kotlin

发现两个kotlin出现版本不同的问题,所以ArraysKt中找不到copyInto方法。

解决方法:

在 minio 的依赖中排除 okhttp 依赖,再单独引入所需的 okhttp 依赖。​           PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(MinIOConfig.MINIO_BUCKET_NAME).object(fileUrl)                   .stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build();           //文件名称相同会覆盖           minioClient.putObject(objectArgs);​           if (inputStream != null) {               inputStream.close();           }           if (in != null) {               in.close();           }           return MinIOConfig.MINIO_END_POINT+ "/" + MinIOConfig.MINIO_BUCKET_NAME + "/" + fileUrl;​       }   }

实现文件上传到minIO的主要代码就是putObject()方法

它需要我们创建一个新的PutObjectArgs对象的构建器(Builder),用于设置上传文件所需的参数

.bucket(MinIOConfig.MINIO_BUCKET_NAME):设置要上传到的MinIO存储桶(bucket)的名称

.object(fileUrl):设置要上传的对象(文件)的名称,表示文件在存储桶中的路径和名称。在引入的 okhttp 的依赖中排除 kotlin 的依赖,再单独引入所需 kotlin 依赖。kotlin的版本冲突问题_io.minio.s3base.(s3base.java:104)-CSDN博客

如果出现Non-XML response from server的错误,那就很有可能是在yml文件中端口号配置错误了(浏览器访问端口9001,java API端口是9000),我就是端口之前写错过,找了半天qwq。

<dependency>    <groupId>io.minio</groupId>    <artifactId>minio</artifactId>    <version>8.5.2</version>    <exclusions>       <exclusion>          <artifactId>okhttp</artifactId>          <groupId>com.squareup.okhttp3</groupId>       </exclusion>    </exclusions></dependency>​<dependency>    <groupId>com.squareup.okhttp3</groupId>    <artifactId>okhttp</artifactId>    <version>4.8.1</version>    <exclusions>       <exclusion>          <artifactId>kotlin-stdlib</artifactId>          <groupId>org.jetbrains.kotlin</groupId>       </exclusion>    </exclusions></dependency>​<dependency>    <groupId>org.jetbrains.kotlin</groupId>    <artifactId>kotlin-stdlib</artifactId>    <version>1.3.70</version></dependency>

详细可以看springboot引入minio导致的okhttp、

文件大小以及超时时间。

接下来重新运行项目,应该就不会报错了

通过debug来了解流程

可以通过前端直接发送请求,也可以用postman发送请求,根据自己的情况来

我们可以看到图片已经上传到minio中了

接下来我们通过访问给前端返回url看是否可以查看图片如果可以,就说明成功了,如果不可以,可能是url写错或者忘记在创建PutObjectArgs时使用contentType(file.getContentType())


好了,以上就是根据我的项目来实现MinIo文件上传功能,以及遇到的一些问题和解决方法,希望对大家有所帮助。