ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileTypeUtils.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java
@@ -5,6 +5,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; @@ -41,17 +42,15 @@ { try { if (!FileUtils.isValidFilename(fileName)) if (!FileUtils.checkAllowDownload(fileName)) { throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName)); } String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1); String filePath = RuoYiConfig.getDownloadPath() + fileName; response.setCharacterEncoding("utf-8"); response.setContentType("multipart/form-data"); response.setHeader("Content-Disposition", "attachment;fileName=" + FileUtils.setFileDownloadHeader(request, realFileName)); response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); FileUtils.setAttachmentResponseHeader(response, realFileName); FileUtils.writeBytes(filePath, response.getOutputStream()); if (delete) { @@ -92,18 +91,28 @@ * 本地资源通用下载 */ @GetMapping("/common/download/resource") public void resourceDownload(String name, HttpServletRequest request, HttpServletResponse response) throws Exception public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response) throws Exception { // 本地资源路径 String localPath = RuoYiConfig.getProfile(); // 数据库资源地址 String downloadPath = localPath + StringUtils.substringAfter(name, Constants.RESOURCE_PREFIX); // 下载名称 String downloadName = StringUtils.substringAfterLast(downloadPath, "/"); response.setCharacterEncoding("utf-8"); response.setContentType("multipart/form-data"); response.setHeader("Content-Disposition", "attachment;fileName=" + FileUtils.setFileDownloadHeader(request, downloadName)); FileUtils.writeBytes(downloadPath, response.getOutputStream()); try { if (!FileUtils.checkAllowDownload(resource)) { throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource)); } // 本地资源路径 String localPath = RuoYiConfig.getProfile(); // 数据库资源地址 String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX); // 下载名称 String downloadName = StringUtils.substringAfterLast(downloadPath, "/"); response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); FileUtils.setAttachmentResponseHeader(response, downloadName); FileUtils.writeBytes(downloadPath, response.getOutputStream()); } catch (Exception e) { log.error("下载文件失败", e); } } } ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileTypeUtils.java
对比新文件 @@ -0,0 +1,47 @@ package com.ruoyi.common.utils.file; import java.io.File; import org.apache.commons.lang3.StringUtils; /** * 文件类型工具类 * * @author ruoyi */ public class FileTypeUtils { /** * 获取文件类型 * <p> * 例如: ruoyi.txt, 返回: txt * * @param file 文件名 * @return 后缀(不含".") */ public static String getFileType(File file) { if (null == file) { return StringUtils.EMPTY; } return getFileType(file.getName()); } /** * 获取文件类型 * <p> * 例如: ruoyi.txt, 返回: txt * * @param fileName 文件名 * @return 后缀(不含".") */ public static String getFileType(String fileName) { int separatorIndex = fileName.lastIndexOf("."); if (separatorIndex < 0) { return ""; } return fileName.substring(separatorIndex + 1).toLowerCase(); } } ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java
@@ -7,7 +7,11 @@ import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.ArrayUtils; import com.ruoyi.common.utils.StringUtils; /** * 文件处理工具类 @@ -105,14 +109,37 @@ } /** * 检查文件是否可下载 * * @param resource 需要下载的文件 * @return true 正常 false 非法 */ public static boolean checkAllowDownload(String resource) { // 禁止目录上跳级别 if (StringUtils.contains(resource, "..")) { return false; } // 检查允许下载的文件规则 if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource))) { return true; } // 不在允许下载的文件规则 return false; } /** * 下载文件名重新编码 * * @param request 请求对象 * @param fileName 文件名 * @return 编码后的文件名 */ public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException { final String agent = request.getHeader("USER-AGENT"); String filename = fileName; @@ -139,4 +166,38 @@ } return filename; } /** * 下载文件名重新编码 * * @param response 响应对象 * @param realFileName 真实文件名 * @return */ public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException { String percentEncodedFileName = percentEncode(realFileName); StringBuilder contentDispositionValue = new StringBuilder(); contentDispositionValue.append("attachment; filename=") .append(percentEncodedFileName) .append(";") .append("filename*=") .append("utf-8''") .append(percentEncodedFileName); response.setHeader("Content-disposition", contentDispositionValue.toString()); } /** * 百分号编码工具方法 * * @param s 需要百分号编码的字符串 * @return 百分号编码后的字符串 */ public static String percentEncode(String s) throws UnsupportedEncodingException { String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString()); return encode.replaceAll("\\+", "%20"); } }