fix: 优化逻辑
This commit is contained in:
parent
9c52bb1c73
commit
76821ca786
@ -3,7 +3,9 @@ package com.yfd.platform.data.controller;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
@ -495,6 +497,9 @@ public class FishDraftDataController {
|
||||
@GetMapping("/previewFile")
|
||||
@Operation(summary = "预览临时文件内容")
|
||||
public void previewFile(@RequestParam String taskId, @RequestParam String filename, @RequestParam String type, HttpServletRequest request, HttpServletResponse response) {
|
||||
// 解码 URL 编码的 filename(处理中文文件名)
|
||||
String decodedFilename = URLDecoder.decode(filename, StandardCharsets.UTF_8);
|
||||
log.debug("原始文件名: {}, 解码后: {}", filename, decodedFilename);
|
||||
|
||||
ImportTask importTask = importTaskService.getById(taskId);
|
||||
String resultJson = importTask.getResultJson();
|
||||
@ -502,9 +507,9 @@ public class FishDraftDataController {
|
||||
String dir = "1".equals(type) ? "images" : "videos";
|
||||
if (resultJson != null && !resultJson.isEmpty()) {
|
||||
try {
|
||||
FishImportResult importResult = objectMapper.readValue(resultJson, FishImportResult.class);
|
||||
String tempDir = importResult.getTempDir();
|
||||
filePath = tempDir + File.separator + dir + File.separator + filename;
|
||||
// FishImportResult importResult = objectMapper.readValue(resultJson, FishImportResult.class);
|
||||
String tempDir = importTask.getTempDir();
|
||||
filePath = tempDir + File.separator + dir + File.separator + decodedFilename;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
// ignore parse error
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package com.yfd.platform.data.utils;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
@ -364,22 +366,99 @@ public class ZipFileUtil {
|
||||
}
|
||||
|
||||
private static String saveFileToDir(InputStream is, File tempDir, String subFolder, String fileName) throws IOException {
|
||||
// 使用 Hutool 构建文件路径
|
||||
String safeFileName = sanitizeFileName(fileName);
|
||||
File folder = new File(tempDir, subFolder);
|
||||
if (!folder.exists()) {
|
||||
folder.mkdirs();
|
||||
|
||||
// 使用 Hutool 创建目录(会自动创建父目录)
|
||||
FileUtil.mkdir(folder);
|
||||
|
||||
log.info("保存文件: fileName{} -> safeFileName{}->subFolder{}", fileName, safeFileName,subFolder);
|
||||
// 构建完整文件路径
|
||||
File file = new File(folder, safeFileName);
|
||||
|
||||
// 安全检查:防止目录穿越
|
||||
String canonicalPath = file.getCanonicalPath();
|
||||
String canonicalDir = folder.getCanonicalPath();
|
||||
if (!canonicalPath.startsWith(canonicalDir)) {
|
||||
throw new IOException("非法的文件路径: " + fileName);
|
||||
}
|
||||
|
||||
File file = new File(folder, fileName);
|
||||
try (FileOutputStream fos = new FileOutputStream(file)) {
|
||||
byte[] buffer = new byte[4096];
|
||||
int len;
|
||||
while ((len = is.read(buffer)) > 0) {
|
||||
fos.write(buffer, 0, len);
|
||||
}
|
||||
// 使用 Hutool 从流复制到文件
|
||||
try {
|
||||
FileUtil.writeFromStream(is, file);
|
||||
log.debug("保存文件: {} -> {}, 大小: {} bytes", fileName, safeFileName, file.length());
|
||||
} catch (Exception e) {
|
||||
throw new IOException("保存文件失败: " + fileName, e);
|
||||
}
|
||||
|
||||
return file.getAbsolutePath();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 清理和标准化文件名,确保在 Linux 上正确显示中文
|
||||
*/
|
||||
private static String sanitizeFileName(String fileName) {
|
||||
if (StrUtil.isBlank(fileName)) {
|
||||
return "unnamed_" + System.currentTimeMillis();
|
||||
}
|
||||
|
||||
// 使用 Hutool 去除首尾空格
|
||||
String sanitized = StrUtil.trim(fileName);
|
||||
|
||||
// 替换非法字符(Linux/Windows 都不允许的字符)
|
||||
sanitized = sanitized.replaceAll("[\\\\/:*?\"<>|]", "_");
|
||||
|
||||
// 去除连续的下划线
|
||||
sanitized = sanitized.replaceAll("_+", "_");
|
||||
|
||||
// 如果文件名过长,截断(Linux 文件名最大 255 字节)
|
||||
byte[] bytes = sanitized.getBytes(StandardCharsets.UTF_8);
|
||||
if (bytes.length > 200) {
|
||||
String extension = "";
|
||||
int dotIndex = sanitized.lastIndexOf('.');
|
||||
if (dotIndex > 0 && dotIndex < sanitized.length() - 1) {
|
||||
extension = sanitized.substring(dotIndex);
|
||||
sanitized = sanitized.substring(0, dotIndex);
|
||||
}
|
||||
|
||||
// 重新计算长度
|
||||
bytes = sanitized.getBytes(StandardCharsets.UTF_8);
|
||||
int maxNameLength = 200 - extension.getBytes(StandardCharsets.UTF_8).length;
|
||||
|
||||
if (bytes.length > maxNameLength) {
|
||||
// 安全截断,避免切断多字节字符
|
||||
sanitized = StrUtil.subPre(sanitized, maxNameLength);
|
||||
}
|
||||
sanitized = sanitized + extension;
|
||||
}
|
||||
|
||||
// 确保文件名不为空
|
||||
if (StrUtil.isBlank(sanitized) || ".".equals(sanitized)) {
|
||||
return "file_" + System.currentTimeMillis();
|
||||
}
|
||||
|
||||
return sanitized;
|
||||
}
|
||||
|
||||
// private static String saveFileToDir(InputStream is, File tempDir, String subFolder, String fileName) throws IOException {
|
||||
// File folder = new File(tempDir, subFolder);
|
||||
// if (!folder.exists()) {
|
||||
// folder.mkdirs();
|
||||
// }
|
||||
//
|
||||
// File file = new File(folder, fileName);
|
||||
// try (FileOutputStream fos = new FileOutputStream(file)) {
|
||||
// byte[] buffer = new byte[4096];
|
||||
// int len;
|
||||
// while ((len = is.read(buffer)) > 0) {
|
||||
// fos.write(buffer, 0, len);
|
||||
// }
|
||||
// }
|
||||
// return file.getAbsolutePath();
|
||||
// }
|
||||
|
||||
private static boolean isImageFile(String fileName) {
|
||||
return fileName.endsWith(".jpg") || fileName.endsWith(".jpeg") ||
|
||||
fileName.endsWith(".png") || fileName.endsWith(".gif") ||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user