下载
https://www.minio.org.cn/download.shtml#/windows
启动
minio.exe server C:\zhushanglin\WindowsSoft\minio\uploadFile
登录
localhost:9000
使用
第一步 创建桶
第二步 设置权限策略
第三步 添加依赖
<!-- Minio 文件存储 --> <dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>8.2.1</version> </dependency>
yml配置
# Minio配置 minio: url: http://localhost:9000 accessKey: minioadmin secretKey: minioadmin bucketName: defect
MinioConfig配置
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import io.minio.MinioClient; /** * Minio 配置信息 * */ @Configuration @ConfigurationProperties(prefix = "minio") public class MinioConfig { /** * 服务地址 */ private static String url; /** * 用户名 */ private static String accessKey; /** * 密码 */ private static String secretKey; /** * 存储桶名称 */ private static String bucketName; public static String getUrl() { return url; } public void setUrl(String url) { MinioConfig.url = url; } public static String getAccessKey() { return accessKey; } public void setAccessKey(String accessKey) { MinioConfig.accessKey = accessKey; } public static String getSecretKey() { return secretKey; } public void setSecretKey(String secretKey) { MinioConfig.secretKey = secretKey; } public static String getBucketName() { return bucketName; } public void setBucketName(String bucketName) { MinioConfig.bucketName = bucketName; } @Bean public MinioClient getMinioClient() { return MinioClient.builder().endpoint(url).credentials(accessKey, secretKey).build(); } }
MinioUtil
import java.io.IOException; import java.io.InputStream; import org.springframework.web.multipart.MultipartFile; import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.spring.SpringUtils; import io.minio.GetPresignedObjectUrlArgs; import io.minio.MinioClient; import io.minio.PutObjectArgs; import io.minio.http.Method; /** * Minio 文件存储工具类 * */ public class MinioUtil { /** * 上传文件 * * @param bucketName 桶名称 * @param fileName * @throws IOException */ public static String uploadFile(String bucketName, String fileName, MultipartFile multipartFile) throws IOException { String url = ""; MinioClient minioClient = SpringUtils.getBean(MinioClient.class); try (InputStream inputStream = multipartFile.getInputStream()) { minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(fileName).stream(inputStream, multipartFile.getSize(), -1).contentType(multipartFile.getContentType()).build()); url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(fileName).method(Method.GET).build()); url = url.substring(0, url.indexOf('?')); return ServletUtils.urlDecode(url); } catch (Exception e) { throw new IOException(e.getMessage(), e); } } }
FileUploadUtils
import java.io.File; import java.io.IOException; import java.nio.file.Paths; import java.util.Objects; import org.apache.commons.io.FilenameUtils; import org.springframework.web.multipart.MultipartFile; import com.ruoyi.common.config.MinioConfig; import com.ruoyi.common.config.RuoYiConfig; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.exception.file.FileNameLengthLimitExceededException; import com.ruoyi.common.exception.file.FileSizeLimitExceededException; import com.ruoyi.common.exception.file.InvalidExtensionException; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.uuid.Seq; /** * 文件上传工具类 * */ public class FileUploadUtils { /** * 默认大小 50M */ public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024; /** * 默认的文件名最大长度 100 */ public static final int DEFAULT_FILE_NAME_LENGTH = 100; /** * 本地默认上传的地址 */ private static String defaultBaseDir = RuoYiConfig.getProfile(); /** * Minio默认上传的地址 */ private static String bucketName = MinioConfig.getBucketName(); public static void setDefaultBaseDir(String defaultBaseDir) { FileUploadUtils.defaultBaseDir = defaultBaseDir; } public static String getDefaultBaseDir() { return defaultBaseDir; } public static String getBucketName() { return bucketName; } /** * 以默认配置进行文件上传 * * @param file 上传的文件 * @return 文件名称 * @throws Exception */ public static final String upload(MultipartFile file) throws IOException { try { return upload(getDefaultBaseDir(), file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); } catch (Exception e) { throw new IOException(e.getMessage(), e); } } /** * 根据文件路径上传 * * @param baseDir 相对应用的基目录 * @param file 上传的文件 * @return 文件名称 * @throws IOException */ public static final String upload(String baseDir, MultipartFile file) throws IOException { try { return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); } catch (Exception e) { throw new IOException(e.getMessage(), e); } } /** * 文件上传 * * @param baseDir 相对应用的基目录 * @param file 上传的文件 * @param allowedExtension 上传文件类型 * @return 返回上传成功的文件名 * @throws FileSizeLimitExceededException 如果超出最大大小 * @throws FileNameLengthLimitExceededException 文件名太长 * @throws IOException 比如读写文件出错时 * @throws InvalidExtensionException 文件校验异常 */ public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension) throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException, InvalidExtensionException { int fileNamelength = Objects.requireNonNull(file.getOriginalFilename()).length(); if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH) { throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH); } assertAllowed(file, allowedExtension); String fileName = extractFilename(file); String absPath = getAbsoluteFile(baseDir, fileName).getAbsolutePath(); file.transferTo(Paths.get(absPath)); return getPathFileName(baseDir, fileName); } /** * 以默认BucketName配置上传到Minio服务器 * * @param file 上传的文件 * @return 文件名称 * @throws Exception */ public static final String uploadMinio(MultipartFile file) throws IOException { try { return uploadMinino(getBucketName(), file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); } catch (Exception e) { throw new IOException(e.getMessage(), e); } } /** * 自定义bucketName配置上传到Minio服务器 * * @param file 上传的文件 * @return 文件名称 * @throws Exception */ public static final String uploadMinio(MultipartFile file, String bucketName) throws IOException { try { return uploadMinino(bucketName, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); } catch (Exception e) { throw new IOException(e.getMessage(), e); } } private static final String uploadMinino(String bucketName, MultipartFile file, String[] allowedExtension) throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException, InvalidExtensionException { int fileNamelength = file.getOriginalFilename().length(); if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH) { throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH); } assertAllowed(file, allowedExtension); try { String fileName = extractFilename(file); String pathFileName = MinioUtil.uploadFile(bucketName, fileName, file); return pathFileName; } catch (Exception e) { throw new IOException(e.getMessage(), e); } } /** * 编码文件名 */ public static final String extractFilename(MultipartFile file) { return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(), FilenameUtils.getBaseName(file.getOriginalFilename()), Seq.getId(Seq.uploadSeqType), getExtension(file)); } public static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException { File desc = new File(uploadDir + File.separator + fileName); if (!desc.exists()) { if (!desc.getParentFile().exists()) { desc.getParentFile().mkdirs(); } } return desc; } public static final String getPathFileName(String uploadDir, String fileName) throws IOException { int dirLastIndex = RuoYiConfig.getProfile().length() + 1; String currentDir = StringUtils.substring(uploadDir, dirLastIndex); return Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + fileName; } /** * 文件大小校验 * * @param file 上传的文件 * @return * @throws FileSizeLimitExceededException 如果超出最大大小 * @throws InvalidExtensionException */ public static final void assertAllowed(MultipartFile file, String[] allowedExtension) throws FileSizeLimitExceededException, InvalidExtensionException { long size = file.getSize(); if (size > DEFAULT_MAX_SIZE) { throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024); } String fileName = file.getOriginalFilename(); String extension = getExtension(file); if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension)) { if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION) { throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension, fileName); } else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION) { throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension, fileName); } else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION) { throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension, fileName); } else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION) { throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension, fileName); } else { throw new InvalidExtensionException(allowedExtension, extension, fileName); } } } /** * 判断MIME类型是否是允许的MIME类型 * * @param extension * @param allowedExtension * @return */ public static final boolean isAllowedExtension(String extension, String[] allowedExtension) { for (String str : allowedExtension) { if (str.equalsIgnoreCase(extension)) { return true; } } return false; } /** * 获取文件名的后缀 * * @param file 表单文件 * @return 后缀名 */ public static final String getExtension(MultipartFile file) { String extension = FilenameUtils.getExtension(file.getOriginalFilename()); if (StringUtils.isEmpty(extension)) { extension = MimeTypeUtils.getExtension(Objects.requireNonNull(file.getContentType())); } return extension; } }
controller
/** * 自定义 Minio 服务器上传请求 */ @PostMapping("/uploadMinio") @ResponseBody public AjaxResult uploadFileMinio(MultipartFile file) throws Exception { try { // 上传并返回新文件名称 String fileName = FileUploadUtils.uploadMinio(file); AjaxResult ajax = AjaxResult.success(); ajax.put("url", fileName); ajax.put("fileName", fileName); ajax.put("newFileName", FileUtils.getName(fileName)); ajax.put("originalFilename", file.getOriginalFilename()); return ajax; } catch (Exception e) { return AjaxResult.error(e.getMessage()); } }
测试