一、minio简介

MinIO 是在 GNU Affero 通用公共许可证 v3.0 下发布的高性能对象存储。 它是与 Amazon S3 云存储服务兼容的 API,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等

二、minio安装

参考我的另一篇文章:https://www.cnblogs.com/lvlinguang/p/15770479.html

一、java中使用

1、pom文件引用

<!-- minio 文件服务客户端 -->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>6.0.11</version>
</dependency>

2、添加配置文件

  • url:minio服务器的接口地址,不是访问地址
  • accessKey/secretKey:登录minio系统,新建Service Accounts
config:
minio:
url: http://192.168.3.15:9000
accessKey: 66SBZWYDSO0DZRSE1U3T
secretKey: S+p8mWE8aykZ0YsRtC0ef35qUS7fUbkITITJdjS6

3、注册MinioClient

@Data
@Configuration
@ConfigurationProperties(prefix = "config.minio")
public class MinioConfig {
/**
* minio 服务地址 http://ip:port
*/
private String url; /**
* 用户名
*/
private String accessKey; /**
* 密码
*/
private String secretKey; @SneakyThrows
@Bean
@RefreshScope
public MinioClient minioClient(){
return new MinioClient(url, accessKey, secretKey);
}
}

4、minio工具类

/**
* minio工具类
*
* @author lvlinguang
* @date 2022-01-07 12:26
* @see http://docs.minio.org.cn/docs/master/java-client-api-reference
*/
@Component
public class MinioUtils { @Autowired
private MinioClient client; /**
* 创建bucket
*
* @param bucketName
*/
@SneakyThrows
public void createBucket(String bucketName) {
if (!client.bucketExists(bucketName)) {
client.makeBucket(bucketName);
}
} /**
* 获取所有bucket
*
* @return
*/
@SneakyThrows
public List<Bucket> listAllBuckets() {
return client.listBuckets();
} /**
* bucket详情
*
* @param bucketName 名称
* @return
*/
@SneakyThrows
public Optional<Bucket> getBucket(String bucketName) {
return client.listBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst();
} /**
* 删除bucket
*
* @param bucketName 名称
*/
@SneakyThrows
public void removeBucket(String bucketName) {
client.removeBucket(bucketName);
} /**
* 上传文件
*
* @param bucketName bucket名称
* @param objectName 文件名称
* @param stream 文件流
* @throws Exception
*/
@SneakyThrows
public void uploadFile(String bucketName, String objectName, InputStream stream) throws Exception {
this.uploadFile(bucketName, objectName, stream, (long) stream.available(), "application/octet-stream");
} /**
* 上传文件
*
* @param bucketName bucket名称
* @param objectName 文件名称
* @param stream 文件流
* @param size 大小
* @param contextType 类型
* @throws Exception
*/
@SneakyThrows
public void uploadFile(String bucketName, String objectName, InputStream stream, long size, String contextType) throws Exception {
//如果bucket不存在,则创建
this.createBucket(bucketName);
client.putObject(bucketName, objectName, stream, size, null, null, contextType);
} /**
* 获取文件
*
* @param bucketName bucket名称
* @param objectName 文件名称
* @return
*/
@SneakyThrows
public InputStream getFile(String bucketName, String objectName) {
return client.getObject(bucketName, objectName);
} /**
* 根据文件前置查询文件
*
* @param bucketName bucket名称
* @param prefix 前缀
* @param recursive 是否递归查询
* @return
*/
@SneakyThrows
public List<MinioItem> listAllFileByPrefix(String bucketName, String prefix, boolean recursive) {
List<MinioItem> objectList = new ArrayList<>();
Iterable<Result<Item>> objectsIterator = client
.listObjects(bucketName, prefix, recursive);
while (objectsIterator.iterator().hasNext()) {
objectList.add(new MinioItem(objectsIterator.iterator().next().get()));
}
return objectList;
} /**
* 删除文件
*
* @param bucketName bucket名称
* @param objectName 文件名称
*/
@SneakyThrows
public void removeFile(String bucketName, String objectName) {
client.removeObject(bucketName, objectName);
} /**
* 获取文件外链
*
* @param bucketName bucket名称
* @param objectName 文件名称
* @param expires 过期时间 <=7
* @return
*/
@SneakyThrows
public String getFileURL(String bucketName, String objectName, Integer expires) {
return client.presignedGetObject(bucketName, objectName, expires);
} /**
* 获取文件信息
*
* @param bucketName bucket名称
* @param objectName 文件名称
* @return
*/
@SneakyThrows
public ObjectStat getFileInfo(String bucketName, String objectName) {
return client.statObject(bucketName, objectName);
}
}

5、文件操作类

/**
* 系统文件工具类
*
* @author lvlinguang
* @date 2021-02-28 12:30
*/
@Component
public class SysFileUtils { /**
* 文件服务器中的目录分隔符
*/
public static final String SEPRETOR = "/"; @Autowired
private MinioUtils minioUtils; /**
* 文件上传
*
* @param object 文件对你
* @param bucketName bucket名称
* @return
*/
@SneakyThrows
public MinioObject uploadFile(MultipartFile object, String bucketName) {
return this.uploadFile(object.getInputStream(), bucketName, object.getOriginalFilename());
} /**
* 文件上传
*
* @param object 文件对你
* @param bucketName bucket名称
* @param fileName 文件名
* @return
*/
@SneakyThrows
public MinioObject uploadFile(MultipartFile object, String bucketName, String fileName) {
return this.uploadFile(object.getInputStream(), bucketName, fileName);
} /**
* 文件上传
*
* @param object 文件对你
* @param bucketName bucket名称
* @param randomFileName 文件名是否随机(是:按年/月/日/随机值储存,否:按原文件名储存)
* @return
*/
@SneakyThrows
public MinioObject uploadFile(MultipartFile object, String bucketName, Boolean randomFileName) {
//文件名
String fileName = object.getOriginalFilename();
if (randomFileName) {
//扩展名
String extName = FileUtil.extName(object.getOriginalFilename());
if (StrUtil.isNotBlank(extName)) {
extName = StrUtil.DOT + extName;
}
//新文件名
fileName = randomFileName(extName);
}
return this.uploadFile(object.getInputStream(), bucketName, fileName);
} /**
* 文件上传
*
* @param object 文件对你
* @param bucketName bucket名称
* @param fileName 文件名
* @return
*/
@SneakyThrows
public MinioObject uploadFile(InputStream object, String bucketName, String fileName) {
try {
minioUtils.uploadFile(bucketName, fileName, object);
return new MinioObject(minioUtils.getFileInfo(bucketName, fileName));
} catch (Exception e) {
throw new Exception(e);
} finally {
if (object != null) {
object.close();
}
}
} /**
* 下载文件
*
* @param response response
* @param url 文件地址(/bucketName/fileName)
*/
public void downloadFile(HttpServletResponse response, String url) {
final String bucketName = getBucketName(url);
final String filePath = getFilePath(url);
this.downloadFile(response, bucketName, filePath);
} /**
* 下载文件
*
* @param response response
* @param bucket bucket名称
* @param fileName 文件名
*/
public void downloadFile(HttpServletResponse response, String bucket, String fileName) {
try (InputStream inputStream = minioUtils.getFile(bucket, fileName)) {
if ("jpg".equals(FileUtil.extName(fileName))) {
response.setContentType("image/jpeg");
} else if ("png".equals(FileUtil.extName(fileName))) {
response.setContentType("image/png");
} else {
response.setContentType("application/octet-stream; charset=UTF-8");
}
IoUtil.copy(inputStream, response.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
}
} /**
* 获取链接地址的 文件名
*
* @param bucketFileUrl
* @return
*/
public static String getFilePath(String bucketFileUrl) {
if (bucketFileUrl == null) {
return null;
}
//去掉第一个分割符
if (bucketFileUrl.startsWith(SEPRETOR)) {
bucketFileUrl = bucketFileUrl.substring(1);
}
return bucketFileUrl.substring(bucketFileUrl.indexOf(SEPRETOR) + 1);
} /**
* 获取链接地址的 bucketName
*
* @param bucketFileUrl 地址(/{bucketName}/{path}/{fileName})
* @return
*/
public static String getBucketName(String bucketFileUrl) {
if (bucketFileUrl == null) {
return null;
}
//去掉第一个分割符
if (bucketFileUrl.startsWith(SEPRETOR)) {
bucketFileUrl = bucketFileUrl.substring(1);
}
return bucketFileUrl.substring(0, bucketFileUrl.indexOf(SEPRETOR));
} /**
* 生成新的文件名
*
* @param extName 扩展名
* @return
*/
public static String randomFileName(String extName) {
LocalDate now = LocalDate.now();
return now.getYear() + SEPRETOR +
getFullNumber(now.getMonthValue()) + SEPRETOR +
getFullNumber(now.getDayOfMonth()) + SEPRETOR +
UUID.randomUUID().toString().replace("-", "") + extName;
} /**
* 得到数字全称,带0
*
* @param number
* @return
*/
public static String getFullNumber(Integer number) {
if (number < 10) {
return "0" + number;
}
return number.toString();
}
}

5、返回包装类

@Data
public class MinioItem { private String objectName;
private Date lastModified;
private String etag;
private Long size;
private String storageClass;
private Owner owner;
private String type; public MinioItem(Item item) {
this.objectName = item.objectName();
this.lastModified = item.lastModified();
this.etag = item.etag();
this.size = (long) item.size();
this.storageClass = item.storageClass();
this.owner = item.owner();
this.type = item.isDir() ? "directory" : "file";
}
} @Data
public class MinioObject { private String bucketName;
private String name;
private Date createdTime;
private Long length;
private String etag;
private String contentType; public MinioObject(ObjectStat os) {
this.bucketName = os.bucketName();
this.name = os.name();
this.createdTime = os.createdTime();
this.length = os.length();
this.etag = os.etag();
this.contentType = os.contentType();
}
}

6、控制器调用

@RestController
@RequestMapping("/file")
public class FileController { public static final String MAPPING = "/file"; @Autowired
private SysFileUtils sysFileUtils; @PostMapping("/upload")
public ApiResponse<MinioObject> upload(@RequestPart("file") MultipartFile file, @RequestParam("bucketName") String bucketName) {
final MinioObject minioObject = sysFileUtils.uploadFile(file, bucketName, true);
return ApiResponse.ok(minioObject);
} @GetMapping("/info/**")
public void getFile(HttpServletRequest request, HttpServletResponse response) {
final String uri = request.getRequestURI();
String fullName = uri.replace(MAPPING + "/info", "");
sysFileUtils.downloadFile(response, fullName);
}
}

7、访问测试

  • 上传测试

-下载/访问测试

地址:http://192.168.3.15:30061/info/avatar/2022/01/07/41aaeb9f56e64c10971b2d9c675ce8fe.jpg

minio文件上传与下载的更多相关文章

  1. java web学习总结(二十四) -------------------Servlet文件上传和下载的实现

    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...

  2. (转载)JavaWeb学习总结(五十)——文件上传和下载

    源地址:http://www.cnblogs.com/xdp-gacl/p/4200090.html 在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传 ...

  3. JavaWeb学习总结,文件上传和下载

    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...

  4. java文件上传和下载

    简介 文件上传和下载是java web中常见的操作,文件上传主要是将文件通过IO流传放到服务器的某一个特定的文件夹下,而文件下载则是与文件上传相反,将文件从服务器的特定的文件夹下的文件通过IO流下载到 ...

  5. 使用jsp/servlet简单实现文件上传与下载

    使用JSP/Servlet简单实现文件上传与下载    通过学习黑马jsp教学视频,我学会了使用jsp与servlet简单地实现web的文件的上传与下载,首先感谢黑马.好了,下面来简单了解如何通过使用 ...

  6. JavaWeb学习总结(五十)——文件上传和下载

    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...

  7. 文件上传和下载(可批量上传)——Spring(三)

    在文件上传和下载(可批量上传)——Spring(二)的基础上,发现了文件下载时,只有在Chrome浏览器下文件名正常显示,还有发布到服务器后,不能上传到指定的文件夹目录,如上传20160310.txt ...

  8. 文件上传和下载(可批量上传)——Spring(二)

    针对SpringMVC的文件上传和下载.下载用之前“文件上传和下载——基础(一)”的依然可以,但是上传功能要修改,这是因为springMVC 都为我们封装好成自己的文件对象了,转换的过程就在我们所配置 ...

  9. Struts2 之 实现文件上传和下载

    Struts2  之 实现文件上传和下载 必须要引入的jar commons-fileupload-1.3.1.jar commons-io-2.2.jar 01.文件上传需要分别在struts.xm ...

随机推荐

  1. Spring Boot,Spring Cloud,Spring Cloud Alibaba 版本选择说明以及整理归纳

    前言 本文的核心目的: 1.方便自己以后的查找,预览,参考 2.帮助那些不知道如何选择版本的朋友进行指引,而不是一味的跟风网上的版本,照抄. Spring Boot 版本 版本查询: https:// ...

  2. socket通道

    一.socket 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket. 就是两个进程,跨计算机,他俩需要通讯的话,需要通过网络对接起来.这就是 socket 的作 ...

  3. Jenkins优化

    目录 一.修改 JVM 的内存配置 二.修改jenkins 主目录 一.修改 JVM 的内存配置 Jenkins 启动方式有两种方式,一种是以 Jdk Jar 方式运行,一种是将 War 包放在 To ...

  4. centos添加本地yum源

    一.简介 centos6系列于2020年11月份已经停止提供服务,现在各大镜像源已经关闭centos6的yum源,需要下载镜像后在本地搭建yum源方便使用. 最好将镜像下载后传到OSS中,这样从阿里云 ...

  5. 转:Java多线程基础问题

    如果你即将去一家从事大型系统研发的公司进行Java面试,不可避免的会有多线程相关的问题.下面是一些针对初学者或者新手的问题,如果你已经具备良好的基础,那么你可以跳过本文,直接尝试针对进阶水平的Java ...

  6. HMS Core版本发布公告

    新增动作捕捉能力.通过简单拍摄即可获得人体3D骨骼关键点数据,广泛应用于虚拟形象.体育运动和医学分析等场景: 3D物体建模能力iOS版本上线. 查看详情>> 新增道路吸附能力.可根据坐标点 ...

  7. 复杂SQL案例:用户退款信息查询

    供参考: select t3.course_id 课程id, t3.user_id 用户ID, u.user_full_name 姓名, -- u.phone, concat(u.company,' ...

  8. mdf与ldf文件如何还原到SQL Server数据库

    1,首先新建两个数据库(Db1,Db2) 在Db1数据库中添加一个表: 然后点击数据库右键-属性-文件-找到文件路径 然后复制这个路径中的Db1的数据,把这两个文件放到其他文件之下 复制之前需要关闭S ...

  9. JAVA直接连接Redis

    引入maven <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</ ...

  10. SpringBoot统一日志打印

    统一日志打印 @Slf4j @Aspect @Component public class ControllerLog { private static final ThreadLocal<Lo ...