正常情况一般我们对文件的上传会优先考虑OSS,可是有些情况特殊的甲方有自己的机房;也不会去考虑OSS,但是要又考虑的文件上传压缩安全的问题;我这里使用的就是OSS来保证数据安全以及压缩(我这边是单体服务)。
我也不太清楚感兴趣的可以看看官网也提供了demo代码
io.minio
minio
8.3.4
me.tongfei
progressbar
0.5.3
com.squareup.okhttp3
okhttp
4.8.1
minio:
endpoint: http://127.0.0.1:9000
accessKey: myname
secretKey: mypassword
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;
}
import com.ruoyi.web.art.dto.MinioProp;
import io.minio.BucketExistsArgs;
import io.minio.MinioClient;
import io.minio.messages.Bucket;
import lombok.Getter;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
@Slf4j
@Component
@Configuration
public class MinioClientConfig {
@Resource
private MinioProp minioProp;
@Getter
private static MinioClient minioClient;
@SneakyThrows(Exception.class)
public static boolean bucketExists(String bucketName) {
return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
}
@SneakyThrows(Exception.class)
public static List getAllBuckets() {
return minioClient.listBuckets();
}
@PostConstruct
public void init() {
try {
minioClient = MinioClient.builder()
.endpoint(minioProp.getEndpoint())
.credentials(minioProp.getAccessKey(), minioProp.getSecretKey())
.build();
} catch (Exception e) {
e.printStackTrace();
log.error("初始化minio配置异常: 【{}】", e.fillInStackTrace());
}
}
}
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.web.art.conf.MinioClientConfig;
import com.ruoyi.web.art.dto.MinioProp;
import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
@Slf4j
@Component
public class MinioUtils {
@Resource
private MinioProp minioProp;
/**
* Minio文件上传
*
* @param file 文件实体
* @param bucketName 所存文件夹(桶名)
*/
public AjaxResult minioUpload(MultipartFile file, String bucketName) {
AjaxResult ajaxResult = new AjaxResult();
ajaxResult.put("code", 500);
try {
MinioClient minioClient = MinioClientConfig.getMinioClient();
// 判断上传文件是否为空
if (null == file || 0 == file.getSize()) {
ajaxResult.put("msg", "上传文件不能为空");
return ajaxResult;
}
// 文件名
String fileName = file.getOriginalFilename();
// 文件名
// 新的文件名 = 存储桶名称_时间戳.后缀名
String fileNameNew = bucketName + "_" + System.currentTimeMillis() + fileName.substring(fileName.lastIndexOf("."));
InputStream inputStream = file.getInputStream();
PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(bucketName).object(fileNameNew)
.stream(inputStream, file.getSize(), -1).contentType(file.getContentType()).build();
//文件名称相同会覆盖
minioClient.putObject(objectArgs);
String fileUrl = minioProp.getEndpoint() + "/" + bucketName + "/" + fileNameNew;
ajaxResult.put("code", 200);
ajaxResult.put("msg", fileUrl);
return ajaxResult;
} catch (Exception e) {
e.printStackTrace();
return ajaxResult;
}
}
/**
* 下载文件
*
* @param originalName 文件路径
*/
public InputStream downloadFile(String bucketName, String originalName, HttpServletResponse response) {
try {
MinioClient minioClient = MinioClientConfig.getMinioClient();
InputStream file = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(originalName).build());
String filename = new String(originalName.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
if (StringUtils.isNotBlank(originalName)) {
filename = originalName;
}
response.setHeader("Content-Disposition", "attachment;filename=" + filename);
ServletOutputStream servletOutputStream = response.getOutputStream();
int len;
byte[] buffer = new byte[1024];
while ((len = file.read(buffer)) > 0) {
servletOutputStream.write(buffer, 0, len);
}
servletOutputStream.flush();
file.close();
servletOutputStream.close();
return file;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.web.art.utils.MinioUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
@Controller
@RequestMapping("/minio")
public class MinioController {
@Resource
private MinioUtils minioUtils;
/**
* 上传
*/
@PreAuthorize("@ss.hasPermi('minio:insert')")
@Log(title = "Minio", businessType = BusinessType.INSERT)
@PostMapping("/upload")
@ResponseBody
public AjaxResult upload(@RequestParam(name = "file", required = false) MultipartFile file) {
minioUtils.minioUpload(file, "test");
return AjaxResult.success();
}
@PreAuthorize("@ss.hasPermi('minio:query')")
@PostMapping("/getFileInputStream")
@ResponseBody
public AjaxResult getFileInputStream(HttpServletResponse response) {
minioUtils.downloadFile("test", "test_1690439416626.jpg", response);
return AjaxResult.success();
}
}
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.web.art.utils.MinioUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
@Controller
@RequestMapping("/minio")
public class MinioController {
@Resource
private MinioUtils minioUtils;
/**
* 上传
*/
@PreAuthorize("@ss.hasPermi('minio:insert')")
@Log(title = "Minio", businessType = BusinessType.INSERT)
@PostMapping("/upload")
@ResponseBody
public AjaxResult upload(@RequestParam(name = "file", required = false) MultipartFile file) {
return minioUtils.minioUpload(file, "test");
}
@PreAuthorize("@ss.hasPermi('minio:query')")
@PostMapping("/getFileInputStream")
@ResponseBody
public AjaxResult getFileInputStream(HttpServletResponse response) {
minioUtils.downloadFile("test", "test_1690439416626.jpg", response);
return AjaxResult.success();
}
}
Minio中Buckets有三种访问策略为:Private、Public、Custom
Private是私有访问我的理解是只有当前用户可以访问或者是只有该用户配置了这个bukets才能进行操作(生产上的一般为该访问模式仅限个人理解我也第一次接错Minio)
Public是指公共访问任何人都可以进行读写(你刚上传的时候可以打开看一下确定你的功能可以实现并且是你想要的)
Custom按照规则进行访问和读写(没研究明白,谁懂可以评论区留言一下我去了解一下)