Commit 1b00dc52 authored by 王飞's avatar 王飞

Feat

1、整合minio。

Reference N/A
parent 8c83550d
...@@ -37,12 +37,19 @@ ...@@ -37,12 +37,19 @@
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<!-- skywalking 链路追踪 -->
<dependency> <dependency>
<groupId>org.apache.skywalking</groupId> <groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId> <artifactId>apm-toolkit-trace</artifactId>
<version>9.0.0</version> <version>9.0.0</version>
</dependency> </dependency>
<!-- 用于将 java.io.File 转换为 MultipartFile -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>
\ No newline at end of file
...@@ -37,127 +37,176 @@ public class CommonController ...@@ -37,127 +37,176 @@ public class CommonController
private static final String FILE_DELIMETER = ","; private static final String FILE_DELIMETER = ",";
/** // /**
* 通用下载请求 // * 通用下载请求
* // *
* @param fileName 文件名称 // * @param fileName 文件名称
* @param delete 是否删除 // * @param delete 是否删除
*/ // */
@GetMapping("/download") // @GetMapping("/download")
public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request) // public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request)
{ // {
try // try
{ // {
if (!FileUtils.checkAllowDownload(fileName)) // if (!FileUtils.checkAllowDownload(fileName))
{ // {
throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName)); // throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName));
} // }
String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1); // String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
String filePath = RuoYiConfig.getDownloadPath() + fileName; // String filePath = RuoYiConfig.getDownloadPath() + fileName;
//
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); // response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
FileUtils.setAttachmentResponseHeader(response, realFileName); // FileUtils.setAttachmentResponseHeader(response, realFileName);
FileUtils.writeBytes(filePath, response.getOutputStream()); // FileUtils.writeBytes(filePath, response.getOutputStream());
if (delete) // if (delete)
{ // {
FileUtils.deleteFile(filePath); // FileUtils.deleteFile(filePath);
} // }
} // }
catch (Exception e) // catch (Exception e)
{ // {
log.error("下载文件失败", e); // log.error("下载文件失败", e);
} // }
} // }
// /**
// * 通用上传请求(单个)
// */
// @PostMapping("/upload")
// public AjaxResult uploadFile(MultipartFile file) throws Exception
// {
// try
// {
// // 上传文件路径
// String filePath = RuoYiConfig.getUploadPath();
// // 上传并返回新文件名称
// String fileName = FileUploadUtils.upload(filePath, file);
// String url = serverConfig.getUrl() + fileName;
// AjaxResult ajax = AjaxResult.success();
// ajax.put("url", url);
// 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());
// }
// }
/** /**
* 通用上传请求(单个) * 通用上传请求(单个)
*/ */
@PostMapping("/upload") @PostMapping("/uploadMinio")
public AjaxResult uploadFile(MultipartFile file) throws Exception public AjaxResult uploadFileMinio(MultipartFile file) throws Exception {
{
try try {
{
// 上传文件路径 String url = FileUploadUtils.uploadMinio(file);
String filePath = RuoYiConfig.getUploadPath();
// 上传并返回新文件名称
String fileName = FileUploadUtils.upload(filePath, file);
String url = serverConfig.getUrl() + fileName;
AjaxResult ajax = AjaxResult.success(); AjaxResult ajax = AjaxResult.success();
ajax.put("url", url); ajax.put("url", url);
ajax.put("fileName", fileName);
ajax.put("newFileName", FileUtils.getName(fileName));
ajax.put("originalFilename", file.getOriginalFilename()); ajax.put("originalFilename", file.getOriginalFilename());
return ajax; return ajax;
}
catch (Exception e) } catch (Exception e) {
{
return AjaxResult.error(e.getMessage()); return AjaxResult.error(e.getMessage());
} }
} }
// /**
// * 通用上传请求(多个)
// */
// @PostMapping("/uploads")
// public AjaxResult uploadFiles(List<MultipartFile> files) throws Exception
// {
// try
// {
// // 上传文件路径
// String filePath = RuoYiConfig.getUploadPath();
// List<String> urls = new ArrayList<String>();
// List<String> fileNames = new ArrayList<String>();
// List<String> newFileNames = new ArrayList<String>();
// List<String> originalFilenames = new ArrayList<String>();
// for (MultipartFile file : files)
// {
// // 上传并返回新文件名称
// String fileName = FileUploadUtils.upload(filePath, file);
// String url = serverConfig.getUrl() + fileName;
// urls.add(url);
// fileNames.add(fileName);
// newFileNames.add(FileUtils.getName(fileName));
// originalFilenames.add(file.getOriginalFilename());
// }
// AjaxResult ajax = AjaxResult.success();
// ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER));
// ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER));
// ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER));
// ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER));
// return ajax;
// }
// catch (Exception e)
// {
// return AjaxResult.error(e.getMessage());
// }
// }
/** /**
* 通用上传请求(多个) * 通用上传请求(多个)
*/ */
@PostMapping("/uploads") @PostMapping("/uploadsMinio")
public AjaxResult uploadFiles(List<MultipartFile> files) throws Exception public AjaxResult uploadFilesMinio(List<MultipartFile> files) throws Exception {
{
try try {
{
// 上传文件路径 List<String> urls = new ArrayList();
String filePath = RuoYiConfig.getUploadPath(); List<String> originalFilenames = new ArrayList();
List<String> urls = new ArrayList<String>();
List<String> fileNames = new ArrayList<String>(); for(MultipartFile file : files) {
List<String> newFileNames = new ArrayList<String>(); String url = FileUploadUtils.uploadMinio(file);
List<String> originalFilenames = new ArrayList<String>();
for (MultipartFile file : files)
{
// 上传并返回新文件名称
String fileName = FileUploadUtils.upload(filePath, file);
String url = serverConfig.getUrl() + fileName;
urls.add(url); urls.add(url);
fileNames.add(fileName);
newFileNames.add(FileUtils.getName(fileName));
originalFilenames.add(file.getOriginalFilename()); originalFilenames.add(file.getOriginalFilename());
} }
AjaxResult ajax = AjaxResult.success(); AjaxResult ajax = AjaxResult.success();
ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER)); ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER));
ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER));
ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER));
ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER)); ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER));
return ajax; return ajax;
}
catch (Exception e) } catch (Exception e) {
{
return AjaxResult.error(e.getMessage()); return AjaxResult.error(e.getMessage());
} }
} }
/** // /**
* 本地资源通用下载 // * 本地资源通用下载
*/ // */
@GetMapping("/download/resource") // @GetMapping("/download/resource")
public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response) // public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response)
throws Exception // throws Exception
{ // {
try // try
{ // {
if (!FileUtils.checkAllowDownload(resource)) // if (!FileUtils.checkAllowDownload(resource))
{ // {
throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource)); // throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource));
} // }
// 本地资源路径 // // 本地资源路径
String localPath = RuoYiConfig.getProfile(); // String localPath = RuoYiConfig.getProfile();
// 数据库资源地址 // // 数据库资源地址
String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX); // String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX);
// 下载名称 // // 下载名称
String downloadName = StringUtils.substringAfterLast(downloadPath, "/"); // String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); // response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
FileUtils.setAttachmentResponseHeader(response, downloadName); // FileUtils.setAttachmentResponseHeader(response, downloadName);
FileUtils.writeBytes(downloadPath, response.getOutputStream()); // FileUtils.writeBytes(downloadPath, response.getOutputStream());
} // }
catch (Exception e) // catch (Exception e)
{ // {
log.error("下载文件失败", e); // log.error("下载文件失败", e);
} // }
} // }
} }
...@@ -144,3 +144,9 @@ xss: ...@@ -144,3 +144,9 @@ xss:
excludes: /system/notice excludes: /system/notice
# 匹配链接 # 匹配链接
urlPatterns: /system/*,/monitor/*,/tool/* urlPatterns: /system/*,/monitor/*,/tool/*
minio:
url: http://49.232.167.247:22038
accessKey: lB7WhZYiQwLzhHPutRGn
secretKey: 7XMWpLm6p4d20OFe9uXKifEyhF3cp4sTCowI2fhJ
bucketName: vehicle-quality-review-oss
\ No newline at end of file
...@@ -20,4 +20,11 @@ public class SystemReviewTaskTest { ...@@ -20,4 +20,11 @@ public class SystemReviewTaskTest {
System.out.println(JSONUtil.toJsonPrettyStr(task)); System.out.println(JSONUtil.toJsonPrettyStr(task));
} }
@Test
public void testOSSUrl() {
String bucket = "vehicle-quality-review-oss";
String url = "http://49.232.167.247:22038/vehicle-quality-review-oss/2023/12/19/1702891760057_20231219102010A002.jpg";
System.out.println();
}
} }
...@@ -138,12 +138,20 @@ ...@@ -138,12 +138,20 @@
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
</dependency> </dependency>
<!-- hutool -->
<dependency> <dependency>
<groupId>cn.hutool</groupId> <groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId> <artifactId>hutool-all</artifactId>
<version>5.8.23</version> <version>5.8.23</version>
</dependency> </dependency>
<!-- minio -->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.2.1</version>
</dependency>
</dependencies> </dependencies>
</project> </project>
\ No newline at end of file
package com.ruoyi.common.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import io.minio.MinioClient;
/**
* Minio 配置信息
*
* @author ruoyi
*/
@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();
}
}
package com.ruoyi.common.utils.file; package com.ruoyi.common.utils.file;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.Objects; import java.util.Objects;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.config.MinioConfig;
import com.ruoyi.common.config.RuoYiConfig; import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.exception.file.FileNameLengthLimitExceededException; import com.ruoyi.common.exception.file.FileNameLengthLimitExceededException;
...@@ -17,7 +21,7 @@ import com.ruoyi.common.utils.uuid.Seq; ...@@ -17,7 +21,7 @@ import com.ruoyi.common.utils.uuid.Seq;
/** /**
* 文件上传工具类 * 文件上传工具类
* *
* @author ruoyi * @author ruoyi
*/ */
public class FileUploadUtils public class FileUploadUtils
...@@ -33,9 +37,14 @@ public class FileUploadUtils ...@@ -33,9 +37,14 @@ public class FileUploadUtils
public static final int DEFAULT_FILE_NAME_LENGTH = 100; public static final int DEFAULT_FILE_NAME_LENGTH = 100;
/** /**
* 默认上传的地址 * 本地默认上传的地址
*/ */
private static String defaultBaseDir = RuoYiConfig.getProfile(); private static String defaultBaseDir = RuoYiConfig.getProfile();
/**
* Minio默认上传的地址
*/
private static String bucketName = MinioConfig.getBucketName();
public static void setDefaultBaseDir(String defaultBaseDir) public static void setDefaultBaseDir(String defaultBaseDir)
{ {
...@@ -46,6 +55,11 @@ public class FileUploadUtils ...@@ -46,6 +55,11 @@ public class FileUploadUtils
{ {
return defaultBaseDir; return defaultBaseDir;
} }
public static String getBucketName()
{
return bucketName;
}
/** /**
* 以默认配置进行文件上传 * 以默认配置进行文件上传
...@@ -117,6 +131,90 @@ public class FileUploadUtils ...@@ -117,6 +131,90 @@ public class FileUploadUtils
return getPathFileName(baseDir, fileName); 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 上传的文件
* @param contentType 文件类型
* @return 文件名称
* @throws Exception
*/
public static final String uploadMinio(File file, String contentType) throws IOException {
return uploadMinio(file2MultipartFile(file, contentType));
}
/**
* 自定义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);
}
}
/**
* 自定义bucketName配置上传到Minio服务器
*
* @param file 上传的文件
* @param contentType 文件类型
* @return 文件名称
* @throws Exception
*/
public static final String uploadMinio(File file, String contentType, String bucketName) throws IOException {
return uploadMinio(file2MultipartFile(file, contentType), bucketName);
}
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);
}
}
/** /**
* 编码文件名 * 编码文件名
*/ */
...@@ -216,7 +314,7 @@ public class FileUploadUtils ...@@ -216,7 +314,7 @@ public class FileUploadUtils
/** /**
* 获取文件名的后缀 * 获取文件名的后缀
* *
* @param file 表单文件 * @param file 表单文件
* @return 后缀名 * @return 后缀名
*/ */
...@@ -229,4 +327,16 @@ public class FileUploadUtils ...@@ -229,4 +327,16 @@ public class FileUploadUtils
} }
return extension; return extension;
} }
}
/**
* java.io.File 转换 MultipartFile
* @param file java.io.File
* @param contentType 文件类型
* @return MultipartFile
* @throws IOException
*/
private static MultipartFile file2MultipartFile(File file, String contentType) throws IOException {
return new MockMultipartFile(file.getName(), file.getName(), contentType, new FileInputStream(file));
}
}
\ No newline at end of file
package com.ruoyi.common.utils.file;
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 文件存储工具类
*
* @author ruoyi
*/
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('?'));
url = url.substring(url.indexOf(bucketName) - 1, url.length());
return ServletUtils.urlDecode(url);
}
catch (Exception e)
{
throw new IOException(e.getMessage(), e);
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment