RuoYi-Vue-Plus OSS对象存储改为本地存储RuoYi-Vue-Plus OSS对象存储改为本地存储,主要逻
"嘿,亲爱的小伙伴们!👋 今天我怀揣着满满的热情,精心准备了一篇文章,希望能像一缕清风,拂过我们求知的心田,带来一些新的思考与启发。让我们携手并进,在知识的海洋中扬帆远航,共同探索、学习、成长吧!🌟"
具体步骤
-
先去gitee仓库下载RuoYi-Vue-Plus项目。地址:gitee.com/dromara/Ruo…
-
成功下载项目并能成功运行
-
在ruoyi-admin模块中找到application.yml文件,添加以下内容
- 在ruoyi-common模块中找到config包下的RuoYiConfig.java文件,添加以下内容,并生成构造方法:
-
在ruoyi-common模块找到utils包,修改FileUtils.java文件、增加FileUploadUtils.java工具类、修改媒体类型工具类 MimeTypeUtils.java
(1)FileUtils.java文件中增加输出指定文件的byte数组方法,代码如下:
/** * 输出指定文件的byte数组 * * @param filePath 文件路径 * @param os 输出流 * @return */ public static void writeBytes(String filePath, OutputStream os) throws IOException { FileInputStream fis = null; try { File file = new File(filePath); if (!file.exists()) { throw new FileNotFoundException(filePath); } fis = new FileInputStream(file); byte[] b = new byte[1024]; int length; while ((length = fis.read(b)) > 0) { os.write(b, 0, length); } } catch (IOException e) { throw e; } finally { IOUtils.close(os); IOUtils.close(fis); } }
(2) FileUploadUtils.java
package com.ruoyi.common.utils.file; 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.uuid.Seq; import org.apache.commons.io.FilenameUtils; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; import java.nio.file.Paths; import java.util.Objects; /** * 文件上传工具类 * * @author 14820 */ 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(); public static void setDefaultBaseDir(String defaultBaseDir) { FileUploadUtils.defaultBaseDir = defaultBaseDir; } public static String getDefaultBaseDir() { return defaultBaseDir; } /** * 以默认配置进行文件上传 * * @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); } /** * 编码文件名 */ 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; } }
(3)在MimeTypeUtils.java 中增加以下代码:
-
找到通用常量信息声明(ruoyi-common→constant→Constants),添加以下内容
-
在ruoyi-framework模块中的config包下新增ServerConfig.java 服务相关配置类
package com.ruoyi.framework.config; import com.ruoyi.common.utils.ServletUtils; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.UnknownHostException; import java.util.Enumeration; /** * 服务相关配置 * * @author ruoyi */ @Component public class ServerConfig { /** * 获取完整的请求路径,包括:域名,端口,上下文访问路径 * * @return 服务地址 */ public String getUrl() { HttpServletRequest request = ServletUtils.getRequest(); return getDomain(request); } public static String getDomain(HttpServletRequest request) { StringBuffer url = request.getRequestURL(); String contextPath = request.getServletContext().getContextPath(); return url.delete(url.length() - request.getRequestURI().length(), url.length()).append(contextPath).toString(); } /** * 获取本机IP地址 (排除虚拟机干扰) * @return 排除虚拟机干扰的IP地址 */ public InetAddress getLocalHostLanAddress() throws UnknownHostException { try { InetAddress candidateAddress = null; // 遍历所有的网络接口 for (Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements();) { NetworkInterface iface = (NetworkInterface) ifaces.nextElement(); // 在所有的接口下再遍历IP for (Enumeration inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements();) { InetAddress inetAddr = (InetAddress) inetAddrs.nextElement(); if (!inetAddr.isLoopbackAddress()) {// 排除loopback类型地址 if (inetAddr.isSiteLocalAddress()) { // 如果是site-local地址,就是它了 return inetAddr; } else if (candidateAddress == null) { // site-local类型的地址未被发现,先记录候选地址 candidateAddress = inetAddr; } } } } if (candidateAddress != null) { return candidateAddress; } // 如果没有发现 non-loopback地址.只能用最次选的方案 InetAddress jdkSuppliedAddress = InetAddress.getLocalHost(); if (jdkSuppliedAddress == null) { throw new UnknownHostException("The JDK InetAddress.getLocalHost() method unexpectedly returned null."); } return jdkSuppliedAddress; } catch (Exception e) { UnknownHostException unknownHostException = new UnknownHostException( "Failed to determine LAN address: " + e); unknownHostException.initCause(e); throw unknownHostException; } } }
-
在ruoyi-framework模块中的config包下找到ResourcesConfig.java,在这个文件添加静态资源映射
-
修改SysOssController.java中文件上传逻辑
-
在对应的接口实现类中新增uploadLocal,本地文件上传逻辑
-
在SysOssServiceImpl.java中找到queryPageList方法 修改文件管理页面查询的逻辑:
-
添加完成上述代码后,可以到登录RuoYi-Vue-Plus管理后台,找到系统管理下的文件管理模块,进入文件管理页面上传文件进行验证。成功上传的效果图如下:
-
在SysOssServiceImpl.java中 找到download方法,增加本地文件下载逻辑
-
添加完成下载的逻辑后,重启项目进入文件管理页面,如果可以正常请求接口下载数据即表示上述的步骤操作是没有问题的。
转载自:https://juejin.cn/post/7419598991120384011