From 03ab867c4f8f7d0e65e063e428e81425569e4265 Mon Sep 17 00:00:00 2001 From: yuejiajun <1530620364@qq.com> Date: Sun, 28 Sep 2025 10:20:16 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=BD=E5=8A=A0=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../demo043/core/TemplateFileLoader.java | 134 ++++++++++++++-- .../demo043/core/Xml2AFSIMTransformation.java | 144 +++++++++++++++--- 2 files changed, 246 insertions(+), 32 deletions(-) diff --git a/src/main/java/com/example/demo/draft/demo043/core/TemplateFileLoader.java b/src/main/java/com/example/demo/draft/demo043/core/TemplateFileLoader.java index fb65135..4580ad7 100644 --- a/src/main/java/com/example/demo/draft/demo043/core/TemplateFileLoader.java +++ b/src/main/java/com/example/demo/draft/demo043/core/TemplateFileLoader.java @@ -12,39 +12,97 @@ import java.util.Map; /** * 模板文件工具类 - * 负责从文件系统或类路径加载模板文件 + * 负责从文件系统或类路径加载模板文件,支持缓存机制提高性能 + * + *
该类提供了以下功能:
+ *使用示例:
+ *+ * // 从类路径加载 + * String template1 = TemplateFileLoader.loadTemplate("classpath:templates/default.html"); + * // 从文件系统加载 + * String template2 = TemplateFileLoader.loadTemplate("file:/opt/templates/default.html"); + * // 默认从类路径加载 + * String template3 = TemplateFileLoader.loadTemplate("templates/default.html"); + *+ * + * @author 岳佳君 + * @version 1.0 */ @Slf4j public class TemplateFileLoader { + /** + * 默认模板目录路径 + */ private static final String DEFAULT_TEMPLATE_DIR = "templates/"; + + /** + * 类路径前缀标识符 + */ private static final String CLASS_PATH_PREFIX = "classpath:"; + + /** + * 文件系统路径前缀标识符 + */ private static final String FILE_PATH_PREFIX = "file:"; - // 模板缓存 + /** + * 模板缓存,使用HashMap存储已加载的模板内容 + * Key: 缓存键(包含路径前缀和模板路径) + * Value: 模板文件内容 + */ private static final Map
该方法会首先检查缓存中是否已存在该模板,如果存在则直接返回缓存内容, + * 否则从类路径读取文件内容并存入缓存。
+ * + * @param templatePath 模板文件路径,可以是相对路径或绝对路径 + * (相对路径相对于类路径根目录) + * @return 模板文件的内容字符串 + * @throws IOException 当模板文件未找到或读取失败时抛出 + * @throws IllegalArgumentException 当templatePath为null或空字符串时抛出 */ public static String loadTemplateFromClasspath(String templatePath) throws IOException { + // 参数校验 + if (templatePath == null || templatePath.trim().isEmpty()) { + throw new IllegalArgumentException("模板路径不能为空"); + } + String cacheKey = CLASS_PATH_PREFIX + templatePath; + + // 检查缓存中是否已存在该模板 if (TEMPLATE_CACHE.containsKey(cacheKey)) { + log.debug("从缓存加载类路径模板: {}", templatePath); return TEMPLATE_CACHE.get(cacheKey); } try { - // 从类路径加载 + // 处理路径格式,确保以"/"开头 String fullPath = templatePath.startsWith("/") ? templatePath : "/" + templatePath; java.io.InputStream inputStream = TemplateFileLoader.class.getResourceAsStream(fullPath); + // 检查文件是否存在 if (inputStream == null) { throw new IOException("模板文件未找到: " + templatePath); } + // 读取文件内容并转换为字符串 String content = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); + + // 存入缓存 TEMPLATE_CACHE.put(cacheKey, content); - log.info("从类路径加载模板: {}", templatePath); + log.info("从类路径加载模板成功: {}", templatePath); return content; } catch (IOException e) { @@ -55,22 +113,43 @@ public class TemplateFileLoader { /** * 从文件系统加载模板文件 + * + *该方法会首先检查缓存中是否已存在该模板,如果存在则直接返回缓存内容, + * 否则从文件系统读取文件内容并存入缓存。
+ * + * @param filePath 模板文件的绝对路径或相对路径(相对于当前工作目录) + * @return 模板文件的内容字符串 + * @throws IOException 当模板文件不存在或读取失败时抛出 + * @throws IllegalArgumentException 当filePath为null或空字符串时抛出 */ public static String loadTemplateFromFileSystem(String filePath) throws IOException { + // 参数校验 + if (filePath == null || filePath.trim().isEmpty()) { + throw new IllegalArgumentException("文件路径不能为空"); + } + String cacheKey = FILE_PATH_PREFIX + filePath; + + // 检查缓存中是否已存在该模板 if (TEMPLATE_CACHE.containsKey(cacheKey)) { + log.debug("从缓存加载文件系统模板: {}", filePath); return TEMPLATE_CACHE.get(cacheKey); } try { Path path = Paths.get(filePath); + + // 检查文件是否存在 if (!Files.exists(path)) { throw new IOException("模板文件不存在: " + filePath); } + // 读取文件内容 String content = Files.readString(path, StandardCharsets.UTF_8); + + // 存入缓存 TEMPLATE_CACHE.put(cacheKey, content); - log.info("从文件系统加载模板: {}", filePath); + log.info("从文件系统加载模板成功: {}", filePath); return content; } catch (IOException e) { @@ -80,12 +159,31 @@ public class TemplateFileLoader { } /** - * 智能加载模板(自动判断路径类型) + * 智能加载模板文件(自动判断路径类型) + * + *根据路径前缀自动选择加载方式:
+ *该方法会清空当前内存中所有的模板缓存,适用于需要强制重新加载模板的场景, + * 比如模板文件内容已更新但缓存还未过期的情况。
*/ public static void clearCache() { + int cacheSize = TEMPLATE_CACHE.size(); TEMPLATE_CACHE.clear(); - log.info("模板缓存已清除"); + log.info("模板缓存已清除,原缓存大小: {}", cacheSize); } /** - * 获取缓存中的模板数量 + * 获取当前缓存中的模板数量 + * + * @return 缓存中模板的数量 */ public static int getCacheSize() { return TEMPLATE_CACHE.size(); } -} + + /** + * 检查指定路径的模板是否已缓存 + * + * @param templatePath 模板路径(需要包含完整的前缀) + * @return 如果模板已缓存返回true,否则返回false + */ + public static boolean isCached(String templatePath) { + return TEMPLATE_CACHE.containsKey(templatePath); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/demo/draft/demo043/core/Xml2AFSIMTransformation.java b/src/main/java/com/example/demo/draft/demo043/core/Xml2AFSIMTransformation.java index f7a4324..8739f78 100644 --- a/src/main/java/com/example/demo/draft/demo043/core/Xml2AFSIMTransformation.java +++ b/src/main/java/com/example/demo/draft/demo043/core/Xml2AFSIMTransformation.java @@ -13,34 +13,87 @@ import java.util.Map; import java.util.Stack; import java.util.regex.Pattern; +/** + * XML转AFSIM格式转换器 + * + *该类提供将XML文件转换为JSON格式并应用正则表达式规则进行键名转换的功能。 + * 采用流式处理方式,适用于处理大型XML文件,避免内存溢出。
+ * + *主要功能:
+ *该方法使用StAX流式API解析XML,适用于处理大型文件。 + * 转换后的JSON格式为对象数组,每个XML根元素对应一个JSON对象。
+ * + * @param xmlFile 输入的XML文件,不能为null + * @param jsonFile 输出的JSON文件,不能为null + * @param rootElement 根元素名称,用于标识每个JSON对象的开始和结束 + * @throws Exception 当文件读写失败、XML解析错误或转换过程中出现异常时抛出 + * @throws IllegalArgumentException 当参数为null或空字符串时抛出 */ public void convertXmlToJson(File xmlFile, File jsonFile, String rootElement) throws Exception { + // 参数校验 + if (xmlFile == null || !xmlFile.exists()) { + throw new IllegalArgumentException("XML文件不存在或为null: " + xmlFile); + } + if (jsonFile == null) { + throw new IllegalArgumentException("JSON文件路径不能为null"); + } + if (rootElement == null || rootElement.trim().isEmpty()) { + throw new IllegalArgumentException("根元素名称不能为空"); + } + log.info("开始XML转JSON转换并应用规则"); + log.debug("输入文件: {}, 输出文件: {}, 根元素: {}", xmlFile.getPath(), jsonFile.getPath(), rootElement); try (FileInputStream xmlInputStream = new FileInputStream(xmlFile); FileWriter jsonWriter = new FileWriter(jsonFile)) { + // 创建XML流读取器 XMLInputFactory factory = XMLInputFactory.newInstance(); XMLStreamReader reader = factory.createXMLStreamReader(xmlInputStream); + // 写入JSON数组开始标记 jsonWriter.write("[\n"); boolean firstObject = true; @@ -52,6 +105,7 @@ public class Xml2AFSIMTransformation { StringBuilder currentText = new StringBuilder(); String currentElement = null; + // 流式解析XML while (reader.hasNext()) { int event = reader.next(); @@ -80,7 +134,7 @@ public class Xml2AFSIMTransformation { String text = reader.getText().trim(); if (!text.isEmpty()) { currentText.append(text); - log.debug("文本内容: {}", text); + log.trace("文本内容: {}", text); } } break; @@ -112,6 +166,7 @@ public class Xml2AFSIMTransformation { jsonWriter.write(json); objectCount++; + // 每处理100个对象刷新一次缓冲区并记录日志 if (objectCount % 100 == 0) { log.info("已处理 {} 个对象", objectCount); jsonWriter.flush(); @@ -125,48 +180,68 @@ public class Xml2AFSIMTransformation { } } + // 写入JSON数组结束标记 jsonWriter.write("\n]"); log.info("转换完成,共处理 {} 个对象", objectCount); } catch (Exception e) { - log.error("转换失败", e); + log.error("XML转JSON转换失败,文件: {}", xmlFile.getPath(), e); throw e; } } /** - * 处理元素的属性 + * 处理XML元素的属性 + * + *将元素的属性添加到当前对象中,属性键名为"元素名@属性名"格式
+ * + * @param reader XML流读取器 + * @param elementStack 元素栈,用于跟踪当前解析路径 + * @param currentObject 当前正在构建的对象 */ private void processAttributesForElement(XMLStreamReader reader, Stack将元素的文本内容添加到当前对象中,键名为完整的元素路径
+ * + * @param elementName 元素名称 + * @param content 元素文本内容 + * @param elementStack 元素栈,用于构建完整路径 + * @param currentObject 当前正在构建的对象 */ private void processElementContent(String elementName, String content, Stack转义JSON中的特殊字符,包括引号、反斜杠、控制字符等
+ * + * @param text 要转义的文本 + * @return 转义后的安全JSON字符串 */ private String escapeJson(String text) { if (text == null) return ""; + return text.replace("\\", "\\\\") .replace("\"", "\\\"") .replace("\b", "\\b") @@ -258,6 +346,11 @@ public class Xml2AFSIMTransformation { /** * 应用正则表达式转换规则到单个对象 + * + *遍历对象的所有键,对每个键应用正则表达式规则进行转换
+ * + * @param originalMap 原始对象映射 + * @return 应用规则转换后的新对象映射 */ private Map遍历所有正则规则,找到第一个匹配的规则并进行替换
+ * + * @param originalKey 原始键名 + * @return 替换后的新键名,如果没有匹配规则则返回null */ private String findAndReplace(String originalKey) { for (Map.Entry