diff --git a/server/pom.xml b/server/pom.xml
index e4601a6f..1f5e46a7 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -50,6 +50,15 @@
org.springframework.boot
spring-boot-starter-freemarker
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+ org.projectlombok
+ lombok
+ true
+
diff --git a/server/src/main/config/application.properties b/server/src/main/config/application.properties
index 0099bc54..c8b6450d 100644
--- a/server/src/main/config/application.properties
+++ b/server/src/main/config/application.properties
@@ -22,6 +22,14 @@ spring.freemarker.expose-request-attributes = true
spring.freemarker.expose-session-attributes = true
spring.freemarker.request-context-attribute = request
spring.freemarker.suffix = .ftl
+# Spring Boot Actuator 健康检查配置
+# 开启健康检查端点
+management.endpoints.web.exposure.include=health,info,metrics
+# 显示详细的健康检查信息(生产环境建议设置为when-authorized)
+management.endpoint.health.show-details=always
+# 启用健康检查组件
+management.health.defaults.enabled=true
+
# office设置
#openoffice或LibreOffice home路径
diff --git a/server/src/main/java/cn/keking/service/FileConvertQueueTask.java b/server/src/main/java/cn/keking/service/FileConvertQueueTask.java
index 3da38d3c..6096b92b 100644
--- a/server/src/main/java/cn/keking/service/FileConvertQueueTask.java
+++ b/server/src/main/java/cn/keking/service/FileConvertQueueTask.java
@@ -73,7 +73,7 @@ public class FileConvertQueueTask {
TimeUnit.SECONDS.sleep(10);
} catch (Exception ex) {
Thread.currentThread().interrupt();
- ex.printStackTrace();
+ logger.error("Failed to sleep after exception", ex);
}
logger.info("处理预览转换任务异常,url:{}", url, e);
}
diff --git a/server/src/main/java/cn/keking/service/FileHandlerService.java b/server/src/main/java/cn/keking/service/FileHandlerService.java
index caecdccc..a10a0819 100644
--- a/server/src/main/java/cn/keking/service/FileHandlerService.java
+++ b/server/src/main/java/cn/keking/service/FileHandlerService.java
@@ -178,13 +178,13 @@ public class FileHandlerService implements InitializingBean {
sb.append("");
sb.append("");
} catch (IOException e) {
- e.printStackTrace();
+ logger.error("Failed to read file: {}", outFilePath, e);
}
// 重新写入文件
try (FileOutputStream fos = new FileOutputStream(outFilePath); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fos, StandardCharsets.UTF_8))) {
writer.write(sb.toString());
} catch (IOException e) {
- e.printStackTrace();
+ logger.error("Failed to write file: {}", outFilePath, e);
}
}
@@ -477,14 +477,14 @@ public class FileHandlerService implements InitializingBean {
originFileName = URLDecoder.decode(originFileName, uriEncoding); //转义的文件名 解下出原始文件名
attribute.setSkipDownLoad(true);
} catch (UnsupportedEncodingException e) {
- e.printStackTrace();
+ logger.error("Failed to decode file name: {}", originFileName, e);
}
}
if (UrlEncoderUtils.hasUrlEncoded(originFileName)) { //判断文件名是否转义
try {
originFileName = URLDecoder.decode(originFileName, uriEncoding); //转义的文件名 解下出原始文件名
} catch (UnsupportedEncodingException e) {
- e.printStackTrace();
+ logger.error("Failed to decode file name: {}", originFileName, e);
}
}else {
url = WebUtils.encodeUrlFileName(url); //对未转义的url进行转义
diff --git a/server/src/main/java/cn/keking/service/impl/CadFilePreviewImpl.java b/server/src/main/java/cn/keking/service/impl/CadFilePreviewImpl.java
index 155821c3..6f75fce7 100644
--- a/server/src/main/java/cn/keking/service/impl/CadFilePreviewImpl.java
+++ b/server/src/main/java/cn/keking/service/impl/CadFilePreviewImpl.java
@@ -9,6 +9,8 @@ import cn.keking.utils.DownloadUtils;
import cn.keking.utils.KkFileUtils;
import cn.keking.utils.WebUtils;
import cn.keking.web.filter.BaseUrlFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
@@ -22,6 +24,7 @@ import static cn.keking.service.impl.OfficeFilePreviewImpl.getPreviewType;
@Service
public class CadFilePreviewImpl implements FilePreview {
+ private static final Logger logger = LoggerFactory.getLogger(CadFilePreviewImpl.class);
private static final String OFFICE_PREVIEW_TYPE_IMAGE = "image";
private static final String OFFICE_PREVIEW_TYPE_ALL_IMAGES = "allImages";
@@ -55,7 +58,7 @@ public class CadFilePreviewImpl implements FilePreview {
try {
imageUrls = fileHandlerService.cadToPdf(filePath, outFilePath, cadPreviewType, fileAttribute);
} catch (Exception e) {
- e.printStackTrace();
+ logger.error("Failed to convert CAD file: {}", filePath, e);
}
if (imageUrls == null) {
return otherFilePreview.notSupportedFile(model, fileAttribute, "CAD转换异常,请联系管理员");
diff --git a/server/src/main/java/cn/keking/service/impl/JsonFilePreviewImpl.java b/server/src/main/java/cn/keking/service/impl/JsonFilePreviewImpl.java
index b5d15714..18e0f559 100644
--- a/server/src/main/java/cn/keking/service/impl/JsonFilePreviewImpl.java
+++ b/server/src/main/java/cn/keking/service/impl/JsonFilePreviewImpl.java
@@ -7,6 +7,8 @@ import cn.keking.service.FileHandlerService;
import cn.keking.service.FilePreview;
import cn.keking.utils.DownloadUtils;
import cn.keking.utils.KkFileUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
@@ -23,17 +25,14 @@ import java.nio.file.Paths;
* @since 2025/01/11
* JSON 文件预览处理实现
*/
+@Slf4j
@Service
+@RequiredArgsConstructor
public class JsonFilePreviewImpl implements FilePreview {
private final FileHandlerService fileHandlerService;
private final OtherFilePreviewImpl otherFilePreview;
- public JsonFilePreviewImpl(FileHandlerService fileHandlerService, OtherFilePreviewImpl otherFilePreview) {
- this.fileHandlerService = fileHandlerService;
- this.otherFilePreview = otherFilePreview;
- }
-
@Override
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
String fileName = fileAttribute.getName();
@@ -64,7 +63,7 @@ public class JsonFilePreviewImpl implements FilePreview {
try {
fileData = HtmlUtils.htmlEscape(readJsonFile(filePath, fileName));
} catch (IOException e) {
- e.printStackTrace();
+ log.error("读取JSON文件失败: {}", filePath, e);
}
String base64Data = Base64.encodeBase64String(fileData.getBytes(StandardCharsets.UTF_8));
model.addAttribute("textData", base64Data);
diff --git a/server/src/main/java/cn/keking/service/impl/MediaFilePreviewImpl.java b/server/src/main/java/cn/keking/service/impl/MediaFilePreviewImpl.java
index c0ada479..608deae4 100644
--- a/server/src/main/java/cn/keking/service/impl/MediaFilePreviewImpl.java
+++ b/server/src/main/java/cn/keking/service/impl/MediaFilePreviewImpl.java
@@ -11,6 +11,8 @@ import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import org.springframework.util.ObjectUtils;
@@ -26,6 +28,7 @@ import java.io.File;
@Service
public class MediaFilePreviewImpl implements FilePreview {
+ private static final Logger logger = LoggerFactory.getLogger(MediaFilePreviewImpl.class);
private final FileHandlerService fileHandlerService;
private final OtherFilePreviewImpl otherFilePreview;
private static final String mp4 = "mp4";
@@ -66,7 +69,7 @@ public class MediaFilePreviewImpl implements FilePreview {
convertedUrl = outFilePath; //其他协议的 不需要转换方式的文件 直接输出
}
} catch (Exception e) {
- e.printStackTrace();
+ logger.error("Failed to convert media file: {}", filePath, e);
}
if (convertedUrl == null) {
return otherFilePreview.notSupportedFile(model, fileAttribute, "视频转换异常,请联系管理员");
@@ -148,7 +151,7 @@ public class MediaFilePreviewImpl implements FilePreview {
recorder.record(captured_frame);
}
} catch (Exception e) {
- e.printStackTrace();
+ logger.error("Failed to convert video file to mp4: {}", filePath, e);
return null;
} finally {
if (recorder != null) { //关闭
diff --git a/server/src/main/java/cn/keking/service/impl/SimTextFilePreviewImpl.java b/server/src/main/java/cn/keking/service/impl/SimTextFilePreviewImpl.java
index ce7c6d67..64a8e9e5 100644
--- a/server/src/main/java/cn/keking/service/impl/SimTextFilePreviewImpl.java
+++ b/server/src/main/java/cn/keking/service/impl/SimTextFilePreviewImpl.java
@@ -8,6 +8,8 @@ import cn.keking.service.FilePreview;
import cn.keking.utils.DownloadUtils;
import cn.keking.utils.EncodingDetects;
import cn.keking.utils.KkFileUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
@@ -20,17 +22,14 @@ import java.nio.charset.StandardCharsets;
* Created by kl on 2018/1/17.
* Content :处理文本文件
*/
+@Slf4j
@Service
+@RequiredArgsConstructor
public class SimTextFilePreviewImpl implements FilePreview {
private final FileHandlerService fileHandlerService;
private final OtherFilePreviewImpl otherFilePreview;
- public SimTextFilePreviewImpl(FileHandlerService fileHandlerService,OtherFilePreviewImpl otherFilePreview) {
- this.fileHandlerService = fileHandlerService;
- this.otherFilePreview = otherFilePreview;
- }
-
@Override
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
String fileName = fileAttribute.getName();
@@ -57,7 +56,7 @@ public class SimTextFilePreviewImpl implements FilePreview {
try {
fileData = HtmlUtils.htmlEscape(textData(filePath,fileName));
} catch (IOException e) {
- e.printStackTrace();
+ log.error("读取文本文件失败: {}", filePath, e);
}
model.addAttribute("textData", Base64.encodeBase64String(fileData.getBytes(StandardCharsets.UTF_8)));
return TXT_FILE_PREVIEW_PAGE;
diff --git a/server/src/main/java/cn/keking/utils/OfficeUtils.java b/server/src/main/java/cn/keking/utils/OfficeUtils.java
index fb60423f..ac828b67 100644
--- a/server/src/main/java/cn/keking/utils/OfficeUtils.java
+++ b/server/src/main/java/cn/keking/utils/OfficeUtils.java
@@ -4,6 +4,8 @@ import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.extractor.ExtractorFactory;
import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
@@ -18,6 +20,7 @@ import java.nio.file.Paths;
*/
public class OfficeUtils {
+ private static final Logger logger = LoggerFactory.getLogger(OfficeUtils.class);
private static final String POI_INVALID_PASSWORD_MSG = "password";
/**
@@ -49,7 +52,7 @@ public class OfficeUtils {
try {
propStream.close();//关闭文件输入流
} catch (IOException e) {
- e.printStackTrace();
+ logger.error("Failed to close input stream for file: {}", path, e);
}
}
}
@@ -76,7 +79,7 @@ public class OfficeUtils {
try {
propStream.close();//关闭文件输入流
} catch (IOException e) {
- e.printStackTrace();
+ logger.error("Failed to close input stream for file: {}", path, e);
}
}
}
diff --git a/server/src/main/java/cn/keking/utils/RarUtils.java b/server/src/main/java/cn/keking/utils/RarUtils.java
index 795f9130..6a46d392 100644
--- a/server/src/main/java/cn/keking/utils/RarUtils.java
+++ b/server/src/main/java/cn/keking/utils/RarUtils.java
@@ -1,6 +1,9 @@
package cn.keking.utils;
import cn.keking.config.ConfigConstants;
import cn.keking.service.ZtreeNodeVo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
@@ -15,6 +18,7 @@ import java.util.regex.Pattern;
* create : 2023-04-08
**/
public class RarUtils {
+ private static final Logger logger = LoggerFactory.getLogger(RarUtils.class);
private static final String fileDir = ConfigConstants.getFileDir();
public static byte[] getUTF8BytesFromGBKString(String gbkStr) {
@@ -55,7 +59,7 @@ public class RarUtils {
str = new String(getUTF8BytesFromGBKString(str), StandardCharsets.UTF_8);
}
} catch (UnsupportedEncodingException e) {
- e.printStackTrace();
+ logger.error("Failed to convert string encoding: {}", str, e);
}
}
return str;
diff --git a/server/src/main/java/cn/keking/utils/SimpleEncodingDetects.java b/server/src/main/java/cn/keking/utils/SimpleEncodingDetects.java
index 19e138bb..5b1aec4c 100644
--- a/server/src/main/java/cn/keking/utils/SimpleEncodingDetects.java
+++ b/server/src/main/java/cn/keking/utils/SimpleEncodingDetects.java
@@ -1,5 +1,8 @@
package cn.keking.utils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
@@ -31,6 +34,8 @@ import java.net.URL;
*/
public class SimpleEncodingDetects {
+ private static final Logger logger = LoggerFactory.getLogger(SimpleEncodingDetects.class);
+
/**
* 得到文件的编码
* @param content 文件内容
@@ -65,10 +70,10 @@ public class SimpleEncodingDetects {
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
- e.printStackTrace();
+ logger.error("File not found: {}", file, e);
} catch (IOException e) {
// TODO Auto-generated catch block
- e.printStackTrace();
+ logger.error("Failed to read file: {}", file, e);
}
}
diff --git a/server/src/main/java/cn/keking/utils/WebUtils.java b/server/src/main/java/cn/keking/utils/WebUtils.java
index 53cedb88..f62862cf 100644
--- a/server/src/main/java/cn/keking/utils/WebUtils.java
+++ b/server/src/main/java/cn/keking/utils/WebUtils.java
@@ -87,7 +87,7 @@ public class WebUtils {
try {
urlStr = URLEncoder.encode(urlStr, "UTF-8").replaceAll("\\+", "%20").replaceAll("%3A", ":").replaceAll("%2F", "/").replaceAll("%3F", "?").replaceAll("%26", "&").replaceAll("%3D", "=");
} catch (UnsupportedEncodingException e) {
- e.printStackTrace();
+ LOGGER.error("Failed to encode URL: {}", urlStr, e);
}
}
return urlStr;
@@ -155,7 +155,7 @@ public class WebUtils {
URL urlObj = new URL(url);
url = urlObj.getPath().substring(1);
} catch (MalformedURLException e) {
- e.printStackTrace();
+ LOGGER.error("Failed to parse file URL: {}", url, e);
}
}
// 因为url的参数中可能会存在/的情况,所以直接url.lastIndexOf("/")会有问题
diff --git a/server/src/main/java/cn/keking/web/filter/TrustDirFilter.java b/server/src/main/java/cn/keking/web/filter/TrustDirFilter.java
index f5c5c1f4..c71a21ec 100644
--- a/server/src/main/java/cn/keking/web/filter/TrustDirFilter.java
+++ b/server/src/main/java/cn/keking/web/filter/TrustDirFilter.java
@@ -35,7 +35,7 @@ public class TrustDirFilter implements Filter {
byte[] bytes = FileCopyUtils.copyToByteArray(classPathResource.getInputStream());
this.notTrustDirView = new String(bytes, StandardCharsets.UTF_8);
} catch (IOException e) {
- e.printStackTrace();
+ logger.error("加载notTrustDir.html失败", e);
}
}
diff --git a/server/src/main/java/cn/keking/web/filter/TrustHostFilter.java b/server/src/main/java/cn/keking/web/filter/TrustHostFilter.java
index 6282e162..067a347e 100644
--- a/server/src/main/java/cn/keking/web/filter/TrustHostFilter.java
+++ b/server/src/main/java/cn/keking/web/filter/TrustHostFilter.java
@@ -13,6 +13,8 @@ import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import org.apache.commons.collections4.CollectionUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.FileCopyUtils;
@@ -22,6 +24,7 @@ import org.springframework.util.FileCopyUtils;
*/
public class TrustHostFilter implements Filter {
+ private static final Logger logger = LoggerFactory.getLogger(TrustHostFilter.class);
private String notTrustHostHtmlView;
@Override
@@ -32,7 +35,7 @@ public class TrustHostFilter implements Filter {
byte[] bytes = FileCopyUtils.copyToByteArray(classPathResource.getInputStream());
this.notTrustHostHtmlView = new String(bytes, StandardCharsets.UTF_8);
} catch (IOException e) {
- e.printStackTrace();
+ logger.error("Failed to load notTrustHost.html file", e);
}
}