写给大忙人看的 – Java中上传文件MinIO服务器(2)

写给大忙人看的 – Java中上传文件MinIO服务器(2)上一篇写给大忙人看的-搭建文件服务器MinIO(一),我们已经成功地搭建了MinIO文件服务器,这一篇讲解在Java中如何上传文件至MinIO一、开发前戏1、项目中引入maven依赖<!–minio相关依赖–><dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version

大家好,又见面了,我是你们的朋友全栈君。

上一篇 写给大忙人看的 – 搭建文件服务器 MinIO(一),我们已经成功地搭建了 MinIO 文件服务器,这一篇讲解在 Java 中如何上传文件至 MinIO

一、开发前戏

1、项目中引入 maven 依赖

<!-- minio 相关依赖 -->
<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>3.0.10</version>
</dependency>
<!-- alibaba的fastjson -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.51</version>
</dependency>
<!-- thymeleaf模板引擎 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

这里除了 MinIO 的相关依赖,还添加了 fastjson,thymeleaf 的相关依赖,篇幅原因,其余依赖请自行添加

2、添加配置信息

在 application.yml 文件中加入 MinIO 服务器的相关信息

# minio 文件存储配置信息
minio:
  endpoint: http://127.0.0.1:9000
  accesskey: minioadmin
  secretKey: minioadmin

3、创建实体类

package com.zyxx.email.common.minio;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/** * minio 属性值 */
@Data
@Component
@ConfigurationProperties(prefix = "minio")
public class MinioProp { 
   
    /** * 连接url */
    private String endpoint;
    /** * 用户名 */
    private String accesskey;
    /** * 密码 */
    private String secretKey;
}

这一步,我们将配置文件中 minio 的配置信息通过注解的方式注入到 MinioProp 这个实体中,方便后面我们使用

4、创建核心配置类

package com.zyxx.email.common.minio;

import io.minio.MinioClient;
import io.minio.errors.InvalidEndpointException;
import io.minio.errors.InvalidPortException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/** * minio 核心配置类 */
@Configuration
@EnableConfigurationProperties(MinioProp.class)
public class MinioConfig { 
   

    @Autowired
    private MinioProp minioProp;

    /** * 获取 MinioClient * * @return * @throws InvalidPortException * @throws InvalidEndpointException */
    @Bean
    public MinioClient minioClient() throws InvalidPortException, InvalidEndpointException { 
   
        return new MinioClient(minioProp.getEndpoint(), minioProp.getAccesskey(), minioProp.getSecretKey());
    }
}

通过注入 MinIO 服务器的相关配置信息,得到 MinioClient 对象,我们上传文件依赖此对象

5、上传工具类

package com.zyxx.email.common.minio;

import com.alibaba.fastjson.JSONObject;
import com.zyxx.email.common.redis.RedisUtil;
import com.zyxx.email.utils.DateUtils;
import io.minio.MinioClient;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

@Slf4j
@Component
public class MinioUtils { 
   

    @Autowired
    private MinioClient client;
    @Autowired
    private MinioProp minioProp;

    /** * 创建bucket * * @param bucketName bucket名称 */
    @SneakyThrows
    public void createBucket(String bucketName) { 
   
        if (!client.bucketExists(bucketName)) { 
   
            client.makeBucket(bucketName);
        }
    }

    /** * 上传文件 * * @param file 文件 * @param bucketName 存储桶 * @return */
    public JSONObject uploadFile(MultipartFile file, String bucketName) throws Exception { 
   
        JSONObject res = new JSONObject();
        res.put("code", 0);
        // 判断上传文件是否为空
        if (null == file || 0 == file.getSize()) { 
   
            res.put("msg", "上传文件不能为空");
            return res;
        }
        try { 
   
	       	// 判断存储桶是否存在
	        createBucket(bucketName);
	        // 文件名
	        String originalFilename = file.getOriginalFilename();
	        // 新的文件名 = 存储桶名称_时间戳.后缀名
	        String fileName = bucketName + "_" + System.currentTimeMillis() + originalFilename.substring(originalFilename.lastIndexOf("."));
	        // 开始上传
	        client.putObject(bucketName, fileName, file.getInputStream(), file.getContentType());
	        res.put("code", 1);
	        res.put("msg", minioProp.getEndpoint() + "/" + bucketName + "/" + fileName);
	        return res;
		}  catch (Exception e) { 
   
            log.error("上传文件失败:{}", e.getMessage());
        }
        res.put("msg", "上传失败");
        return res;
    }
}

二、开发进行中

1、编写 Controller

package com.zyxx.email.controller;

import com.alibaba.fastjson.JSONObject;
import com.zyxx.email.common.minio.MinioUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;

@Controller
public class MinioController { 
   

    @Autowired
    private MinioUtils minioUtils;

    @GetMapping("init")
    public String init() { 
   
        return "file";
    }

    /** * 上传 * * @param file * @param request * @return */
    @PostMapping("/upload")
    @ResponseBody
    public String upload(@RequestParam(name = "file", required = false) MultipartFile file, HttpServletRequest request) { 
   
        JSONObject res = null;
        try { 
   
            res = minioUtils.uploadFile(file, "product");
        } catch (Exception e) { 
   
            e.printStackTrace();
            res.put("code", 0);
            res.put("msg", "上传失败");
        }
        return res.toJSONString();
    }
}

2、上传页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>首页</title>
    </head>
    <body>
        <form accept-charset="UTF-8" th:action="@{upload}" method="post" enctype="multipart/form-data" target="_blank">
            文件:<input type="file" name="file"/>
            <input type="submit" value="上传"/>
        </form>
    </body>
</html>

这里我用的 thymeleaf 模板引擎

三、上传测试

1、访问地址

http://localhost:8080/init

测试页面

2、启动 MinIO 文件服务器

3、响应信息

{ 
   "msg":"http://127.0.0.1:9000/product/product_1589105654237.png","code":1}

http://127.0.0.1:9000/product/product_1589105654237.png 就是我们上传之后得到的文件地址了

4、访问文件

MinIO 形式上传的文件也不支持直接访问,我们如果需要直接访问,还需要做如下操作:
更改权限
设置 bucket 的 policy 策略:
设置策略
设置该存储桶下面的文件为 Read and Write,这时我们就可以直接访问了
在这里插入图片描述

四、完整工具类代码

package com.zyxx.email.common.minio;

import com.alibaba.fastjson.JSONObject;
import com.zyxx.email.utils.DateUtils;
import io.minio.MinioClient;
import io.minio.ObjectStat;
import io.minio.messages.Bucket;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.*;

@Slf4j
@Component
public class MinioUtils { 
   

    @Autowired
    private MinioClient client;
    @Autowired
    private MinioProp minioProp;

    /** * 创建bucket * * @param bucketName bucket名称 */
    @SneakyThrows
    public void createBucket(String bucketName) { 
   
        if (!client.bucketExists(bucketName)) { 
   
            client.makeBucket(bucketName);
        }
    }

    /** * 获取全部bucket */
    @SneakyThrows
    public List<Bucket> getAllBuckets() { 
   
        return client.listBuckets();
    }

    /** * 根据bucketName获取信息 * * @param bucketName bucket名称 */
    @SneakyThrows
    public Optional<Bucket> getBucket(String bucketName) { 
   
        return client.listBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst();
    }

    /** * 根据bucketName删除信息 * * @param bucketName bucket名称 */
    @SneakyThrows
    public void removeBucket(String bucketName) { 
   
        client.removeBucket(bucketName);
    }

    /** * 获取文件外链 * * @param bucketName bucket名称 * @param objectName 文件名称 * @param expires 过期时间 <=7 * @return url */
    @SneakyThrows
    public String getObjectURL(String bucketName, String objectName, Integer expires) { 
   
        return client.presignedGetObject(bucketName, objectName, expires);
    }

    /** * 获取文件 * * @param bucketName bucket名称 * @param objectName 文件名称 * @return 二进制流 */
    @SneakyThrows
    public InputStream getObject(String bucketName, String objectName) { 
   
        return client.getObject(bucketName, objectName);
    }

    /** * 上传文件 * * @param bucketName bucket名称 * @param objectName 文件名称 * @param stream 文件流 * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#putObject */
    public void putObject(String bucketName, String objectName, InputStream stream) throws Exception { 
   
        client.putObject(bucketName, objectName, stream, stream.available(), "application/octet-stream");
    }

    /** * 上传文件 * * @param bucketName bucket名称 * @param objectName 文件名称 * @param stream 文件流 * @param size 大小 * @param contextType 类型 * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#putObject */
    public void putObject(String bucketName, String objectName, InputStream stream, long size, String contextType) throws Exception { 
   
        client.putObject(bucketName, objectName, stream, size, contextType);
    }

    /** * 获取文件信息 * * @param bucketName bucket名称 * @param objectName 文件名称 * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#statObject */
    public ObjectStat getObjectInfo(String bucketName, String objectName) throws Exception { 
   
        return client.statObject(bucketName, objectName);
    }

    /** * 删除文件 * * @param bucketName bucket名称 * @param objectName 文件名称 * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#removeObject */
    public void removeObject(String bucketName, String objectName) throws Exception { 
   
        client.removeObject(bucketName, objectName);
    }

    /** * 上传文件 * * @param file 文件 * @param bucketName 存储桶 * @return */
    public JSONObject uploadFile(MultipartFile file, String bucketName) throws Exception { 
   
        JSONObject res = new JSONObject();
        res.put("code", 0);
        // 判断上传文件是否为空
        if (null == file || 0 == file.getSize()) { 
   
            res.put("msg", "上传文件不能为空");
            return res;
        }
        try { 
   
	       	// 判断存储桶是否存在
	        createBucket(bucketName);
	        // 文件名
	        String originalFilename = file.getOriginalFilename();
	        // 新的文件名 = 存储桶名称_时间戳.后缀名
	        String fileName = bucketName + "_" + System.currentTimeMillis() + originalFilename.substring(originalFilename.lastIndexOf("."));
	        // 开始上传
	        client.putObject(bucketName, fileName, file.getInputStream(), file.getContentType());
	        res.put("code", 1);
	        res.put("msg", minioProp.getEndpoint() + "/" + bucketName + "/" + fileName);
	        return res;
		}  catch (Exception e) { 
   
            log.error("上传文件失败:{}", e.getMessage());
        }
        res.put("msg", "上传失败");
        return res;
    }
}

文件的下载功能代码,在后续的文章中会贴出

Java Client 指南地址如下:

https://docs.min.io/docs/java-client-quickstart-guide.html

如您在阅读中发现不足,欢迎留言!!!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/137536.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 后端性能优化的指标有哪些_后端性能优化

    后端性能优化的指标有哪些_后端性能优化网站的性能测试性能测试是性能优化的前提,也是性能优化结果的检查和度量标准。性能测试的常用指标:响应时间并发数目吞吐量。常用的吞吐量指标:  ①TPS(每秒事务数)、②HPS(每秒Http请求数)、③QPS(每秒查询数,)性能计数器。常用的性能计数器有:SystemLoad、对象和线程数、CPU使用、内存使用、磁盘和网络IO等指标。性能测试的几个参考点:性能测试负载测试:系…

    2022年9月18日
    0
  • 版权文字:Power by DedeCms 如何去除?[通俗易懂]

    版权文字:Power by DedeCms 如何去除?[通俗易懂]dedeCMS系统中的版权声明信息中含有“PowerbyDedeCms”字样,如何去除?dedeCMS近期的新版本至2013-6-7更新包以来,不管新版还是旧版更新补丁包,更新后网站页底都会出现powerbydedecms。*一、powerbydedecms什么意思?在我们上网的时候,会见到页面页底很多带powerbydedecms的网站,powerbydede…

    2022年7月13日
    16
  • 2D武侠游戏《剑侠世界》网游单机 搭建教程说明「建议收藏」

    原文链接:http://www.zccode.com/forum.php?mod=viewthread&tid=678&extra=page%3D1%26filter%3Dtypeid%26typeid%3D99该资源说明:游戏名称:剑侠世界单机版…

    2022年4月10日
    50
  • CheckSum 计算工具1——bin文件

    CheckSum 计算工具1——bin文件

    2021年8月27日
    607
  • 联想笔记本键盘亮了屏幕不亮怎么办_电脑开机显示器和键盘都不亮

    联想笔记本键盘亮了屏幕不亮怎么办_电脑开机显示器和键盘都不亮联想电脑显示器不亮怎么办联想电脑显示器不亮解决方法一:1、开机后,我们先不管显示器是否能正常的亮或显示,我们先再次按主机上的重启键,然后我们按一下键中的“numlock”键,也就是台式键盘右边的数字开关切换键。2、如数字开关键上面的数字锁定灯可以正常的亮或正常的灭,这时就说明电脑主机一般没啥事儿了,基本上可以确定是由显示器本身的问题了。3、如无法显示正常的灯亮和灯灭的话,那么基本可以说明是电脑机…

    2022年9月20日
    0
  • 遍历 ArrayList[通俗易懂]

    遍历 ArrayList[通俗易懂]packagecom.List;importjava.util.*;publicclassListTest{publicvoidlisttest(){Listlist=newArrayList();  list.add(“Hello”);  list.add(“World”);  list.add(“HAHAHAHA

    2022年7月22日
    6

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号