文章目录
- 1.minio安装
- 1.拉取镜像
- 2.启动容器
- 3.开启端口
- 1.9090端口
- 2.9000端口
- 4.访问
- 1.网址http://:9090/
- 5.创建一个桶
- 2.minio文件服务基本环境搭建
- 1.创建一个文件模块
- 2.目录结构
- 3.配置依赖
- 3.application.yml 配置
- 4.编写配置类MinioConfig.java,构建minioClient
- 5.FileInfo.java 封装文件信息
- 6.MinioUtil.java 文件工具类
- 7.FileController.java 测试
- 8.启动类 OssApplication.java
- 9.启动测试
- 3.传统模式
- 1.目录结构和类图
- 2.首先引入Lombok的依赖,使用@SneakyThrows注解抛出异常
- 3.StorageService.java 存储的接口
- 4.MinioStorageServiceImpl.java minio实现的接口
- 5.如果有其他的服务比如阿里云也可以实现接口
- 6.FileController.java 按照id来依赖注入进行调用
- 7.测试
- 8.缺点分析
- 4.使用适配器模式优化
- 1.类图
- 2.新增一个阿里云的实现类 AliyunStorageServiceImpl.java
- 3.抽取一个 FileService.java 构造器聚合接口
- 4.StorageConfig.java 配置文件根据application.yml来给构造器注入不同的对象
- 5.application.yml 指定要使用的oss
- 6.FileController.java 组合一个FileService调用里面的方法
- 7.测试
1.minio安装
1.拉取镜像
docker pull minio/minio
2.启动容器
docker run -p 9000:9000 -p 9090:9090 \
--name minio \
-d --restart=always \
-e "MINIO_ACCESS_KEY=" \
-e "MINIO_SECRET_KEY=" \
-v /mydata/minio/data:/data \
minio/minio server \
/data --console-address ":9090" -address ":9000"
3.开启端口
1.9090端口
systemctl start firewalld && firewall-cmd --permanent --add-port=9090/tcp && firewall-cmd --reload && firewall-cmd --query-port=9090/tcp
2.9000端口
systemctl start firewalld && firewall-cmd --permanent --add-port=9000/tcp && firewall-cmd --reload && firewall-cmd --query-port=9000/tcp
4.访问
1.网址http://:9090/
5.创建一个桶
2.minio文件服务基本环境搭建
1.创建一个文件模块
2.目录结构
3.配置依赖
<!-- maven的配置 -->
<!-- 解决java: -source 1.5 中不支持 diamond 运算符 问题 -->
<properties>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.4.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.4.2</version>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-logging</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- minio依赖 -->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.2.0</version>
</dependency>
</dependencies>
<!-- 配置阿里云仓库 -->
<repositories>
<repository>
<id>central</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<layout>default</layout>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<!-- maven打包常规配置 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
3.application.yml 配置
server:
port: 4000
minio:
url: http://:9000
accessKey:
secretKey:
4.编写配置类MinioConfig.java,构建minioClient
package com.sunxiansheng.oss.config;
import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Description: minio配置管理
* @Author sun
* @Create 2024/5/31 9:22
* @Version 1.0
*/
@Configuration
public class MinioConfig {
// minioUrl
@Value("${minio.url}")
private String url;
// minio用户名
@Value("${minio.accessKey}")
private String accessKey;
// minio密码
@Value("${minio.secretKey}")
private String secretKey;
/**
* 构造minioClient
*/
@Bean
public MinioClient getMinioClient() {
return MinioClient.builder().endpoint(url).credentials(accessKey, secretKey).build();
}
}
5.FileInfo.java 封装文件信息
package com.sunxiansheng.oss.entity;
/**
* Description:
* @Author sun
* @Create 2024/5/31 9:47
* @Version 1.0
*/
public class FileInfo {
private String fileName;
private Boolean directoryFlag;
private String etag;
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public Boolean getDirectoryFlag() {
return directoryFlag;
}
public void setDirectoryFlag(Boolean directoryFlag) {
this.directoryFlag = directoryFlag;
}
public String getEtag() {
return etag;
}
public void setEtag(String etag) {
this.etag = etag;
}
}
6.MinioUtil.java 文件工具类
package com.sunxiansheng.oss.util;
import com.sunxiansheng.oss.entity.FileInfo;
import io.minio.*;
import io.minio.messages.Bucket;
import io.minio.messages.Item;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
/**
* Description: minio文件操作工具
* @Author sun
* @Create 2024/5/31 9:30
* @Version 1.0
*/
@Component
public class MinioUtil {
@Resource
private MinioClient minioClient;
/**
* 创建bucket桶
*/
public void createBucket(String bucket) throws Exception {
boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());
if (!exists) {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());
}
}
/**
* 上传文件
*/
public void uploadFile(InputStream inputStream, String bucket, String objectName) throws Exception {
minioClient.putObject(PutObjectArgs.builder().bucket(bucket).object(objectName)
.stream(inputStream, -1, Integer.MAX_VALUE).build());
}
/**
* 列出所有桶
*/
public List<String> getAllBucket() throws Exception {
List<Bucket> buckets = minioClient.listBuckets();
return buckets.stream().map(Bucket::name).collect(Collectors.toList());
}
/**
* 列出当前桶及文件
*/
public List<FileInfo> getAllFile(String bucket) throws Exception {
Iterable<Result<Item>> results = minioClient.listObjects(
ListObjectsArgs.builder().bucket(bucket).build());
List<FileInfo> fileInfoList = new LinkedList<>();
for (Result<Item> result : results) {
FileInfo fileInfo = new FileInfo();
Item item = result.get();
fileInfo.setFileName(item.objectName());
fileInfo.setDirectoryFlag(item.isDir());
fileInfo.setEtag(item.etag());
fileInfoList.add(fileInfo);
}
return fileInfoList;
}
/**
* 下载文件
*/
public InputStream downLoad(String bucket, String objectName) throws Exception {
return minioClient.getObject(
GetObjectArgs.builder().bucket(bucket).object(objectName).build()
);
}
/**
* 删除桶
*/
public void deleteBucket(String bucket) throws Exception {
minioClient.removeBucket(
RemoveBucketArgs.builder().bucket(bucket).build()
);
}
/**
* 删除文件
*/
public void deleteObject(String bucket, String objectName) throws Exception {
minioClient.removeObject(
RemoveObjectArgs.builder().bucket(bucket).object(objectName).build()
);
}
}
7.FileController.java 测试
package com.sunxiansheng.oss.controller;
import com.sunxiansheng.oss.util.MinioUtil;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
* Description:
* @Author sun
* @Create 2024/5/31 9:53
* @Version 1.0
*/
@RestController
public class FileController {
@Resource
private MinioUtil minioUtil;
@RequestMapping("/testGetAllBuckets")
public String testGetAllBuckets() throws Exception {
List<String> allBucket = minioUtil.getAllBucket();
return allBucket.get(0);
}
}
8.启动类 OssApplication.java
package com.sunxiansheng.oss;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
/**
* Description:
* @Author sun
* @Create 2024/5/31 9:20
* @Version 1.0
*/
@SpringBootApplication
@ComponentScan("com.sunxiansheng")
public class OssApplication {
public static void main(String[] args) {
SpringApplication.run(OssApplication.class, args);
}
}
9.启动测试
3.传统模式
1.目录结构和类图
2.首先引入Lombok的依赖,使用@SneakyThrows注解抛出异常
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>
3.StorageService.java 存储的接口
package com.sunxiansheng.oss.service;
import com.sunxiansheng.oss.entity.FileInfo;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
import java.util.List;
/**
* Description:
* @Author sun
* @Create 2024/5/31 10:03
* @Version 1.0
*/
public interface StorageService {
/**
* 创建bucket桶
*/
void createBucket(String bucket);
/**
* 上传文件
*/
void uploadFile(MultipartFile uploadFile, String bucket, String objectName);
/**
* 列出所有桶
*/
List<String> getAllBucket();
/**
* 列出当前桶及文件
*/
List<FileInfo> getAllFile(String bucket);
/**
* 下载文件
*/
InputStream downLoad(String bucket, String objectName);
/**
* 删除桶
*/
void deleteBucket(String bucket);
/**
* 删除文件
*/
void deleteObject(String bucket, String objectName);
}
4.MinioStorageServiceImpl.java minio实现的接口
package com.sunxiansheng.oss.service.impl;
import com.sunxiansheng.oss.entity.FileInfo;
import com.sunxiansheng.oss.service.StorageService;
import com.sunxiansheng.oss.util.MinioUtil;
import lombok.SneakyThrows;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.InputStream;
import java.util.List;
/**
* Description:
* @Author sun
* @Create 2024/5/31 10:06
* @Version 1.0
*/
@Service("minioStorageServiceImpl")
public class MinioStorageServiceImpl implements StorageService {
@Resource
private MinioUtil minioUtil;
@Override
@SneakyThrows // Lombok 自动抛出异常
public void createBucket(String bucket) {
minioUtil.createBucket(bucket);
}
@Override
@SneakyThrows // Lombok 自动抛出异常
public void uploadFile(MultipartFile uploadFile, String bucket, String objectName) {
createBucket(bucket);
if (objectName != null) {
minioUtil.uploadFile(uploadFile.getInputStream(), bucket, objectName + "/" + uploadFile.getName());
} else {
minioUtil.uploadFile(uploadFile.getInputStream(), bucket, uploadFile.getName());
}
}
@Override
@SneakyThrows // Lombok 自动抛出异常
public List<String> getAllBucket() {
return minioUtil.getAllBucket();
}
@Override
@SneakyThrows // Lombok 自动抛出异常
public List<FileInfo> getAllFile(String bucket) {
return minioUtil.getAllFile(bucket);
}
@Override
@SneakyThrows // Lombok 自动抛出异常
public InputStream downLoad(String bucket, String objectName) {
return minioUtil.downLoad(bucket, objectName);
}
@Override
@SneakyThrows // Lombok 自动抛出异常
public void deleteBucket(String bucket) {
minioUtil.deleteBucket(bucket);
}
@Override
@SneakyThrows // Lombok 自动抛出异常
public void deleteObject(String bucket, String objectName) {
minioUtil.deleteObject(bucket, objectName);
}
}
5.如果有其他的服务比如阿里云也可以实现接口
6.FileController.java 按照id来依赖注入进行调用
package com.sunxiansheng.oss.controller;
import com.sunxiansheng.oss.service.StorageService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
* Description:
* @Author sun
* @Create 2024/5/31 9:53
* @Version 1.0
*/
@RestController
public class FileController {
// 这里根据id进行依赖注入,如果还有阿里云的,就注入阿里云的即可
@Resource
private StorageService minioStorageServiceImpl;
@RequestMapping("/listBuckets")
public String testGetAllBuckets() throws Exception {
List<String> allBucket = minioStorageServiceImpl.getAllBucket();
return allBucket.get(0);
}
}
7.测试
8.缺点分析
如果需要修改为阿里云的,则需要修改注入的id,也就是所有的controller都需要修改
4.使用适配器模式优化
1.类图
2.新增一个阿里云的实现类 AliyunStorageServiceImpl.java
package com.sunxiansheng.oss.service.impl;
import com.sunxiansheng.oss.entity.FileInfo;
import com.sunxiansheng.oss.service.StorageService;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Description:
* @Author sun
* @Create 2024/5/31 11:13
* @Version 1.0
*/
@Service("aliyunStorageServiceImpl")
public class AliyunStorageServiceImpl implements StorageService {
@Override
public void createBucket(String bucket) {
}
@Override
public void uploadFile(MultipartFile uploadFile, String bucket, String objectName) {
}
@Override
public List<String> getAllBucket() {
List<String> res = new ArrayList<>();
res.add("aliyunBucket");
return res;
}
@Override
public List<FileInfo> getAllFile(String bucket) {
return Collections.emptyList();
}
@Override
public InputStream downLoad(String bucket, String objectName) {
return null;
}
@Override
public void deleteBucket(String bucket) {
}
@Override
public void deleteObject(String bucket, String objectName) {
}
}
3.抽取一个 FileService.java 构造器聚合接口
package com.sunxiansheng.oss.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* Description:
* @Author sun
* @Create 2024/5/31 10:48
* @Version 1.0
*/
@Service
public class FileService {
private final StorageService storageService;
@Autowired // 构造器注入,如果只有一个构造器,其实可以不加,会自动识别
public FileService(StorageService storageService) {
this.storageService = storageService;
}
/**
* 列出所有桶
*/
public List<String> getAllBucket() {
return storageService.getAllBucket();
}
}
4.StorageConfig.java 配置文件根据application.yml来给构造器注入不同的对象
package com.sunxiansheng.oss.config;
import com.sunxiansheng.oss.service.StorageService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
/**
* Description:
* @Author sun
* @Create 2024/5/31 11:10
* @Version 1.0
*/
@Configuration
public class StorageConfig {
@Value("${storage.service.type}")
private String storageType;
@Resource
private StorageService aliyunStorageServiceImpl;
@Resource
private StorageService minioStorageServiceImpl;
@Bean
public StorageService storageService() {
if ("minio".equals(storageType)) {
return minioStorageServiceImpl;
} else if ("aliyun".equals(storageType)) {
return aliyunStorageServiceImpl;
} else {
throw new IllegalArgumentException("未找到对应的文件存储处理");
}
}
}
5.application.yml 指定要使用的oss
6.FileController.java 组合一个FileService调用里面的方法
package com.sunxiansheng.oss.controller;
import com.sunxiansheng.oss.service.FileService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
* Description:
* @Author sun
* @Create 2024/5/31 9:53
* @Version 1.0
*/
@RestController
public class FileController {
// 这里根据id进行依赖注入,如果还有阿里云的,就注入阿里云的即可
@Resource
private FileService fileService;
@RequestMapping("/listBuckets")
public String testGetAllBuckets() throws Exception {
List<String> allBucket = fileService.getAllBucket();
return allBucket.get(0);
}
}