Java仅使用GSON实现JSON转HTML功能的问题求解
问题描述
我是Java初学者,想要实现任意JSON文件到HTML文件的转换,除使用GSON解析JSON结构外不依赖任何其他外部库。
示例JSON文件内容
{ "doctype": "html", "language": "en", "head": { "meta": { "charset": "utf-8", "viewport": { "width": "device-width", "initial-scale": 1 } }, "title": "Page Not Found" }, "body": { "h1": "Page Not Found", "p": "Sorry, but the page you were trying to view does not exist." } }
预期输出HTML内容
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Page Not Found</title> </head> <body> <h1>Page Not Found</h1> <p>Sorry, but the page you were trying to view does not exist.</p> </body> </html>
当前核心转换代码
private static void getJsonData (JsonObject jsonObject) throws IOException { jsonObject.keySet().forEach(key -> { Object value = jsonObject.get(key); if (value instanceof JsonObject){ try { getJsonData((JsonObject) value); } catch (IOException e) { e.printStackTrace(); } System.out.println("key " + key + " of value " + value + " is a JsonObject"); } else if (value instanceof JsonArray){ try { writeToHtmlFile("<" + key + ">"); } catch (IOException e) { e.printStackTrace(); } System.out.println("key " + key + " of value " + value + " is a JsonArray"); } else { if (Objects.equals(key, "doctype")) { try { writeToHtmlFile("<!DOCTYPE " + value + ">"); } catch (IOException e) { e.printStackTrace(); } } else if (Objects.equals(key, "language")) { try { writeToHtmlFile("<html lang=" + value + ">"); } catch (IOException e) { e.printStackTrace(); } } else { try { writeToHtmlFile("<" + key + ">"); } catch (IOException e) { e.printStackTrace(); } } System.out.println("key " + key + " of value " + value + " is an entry"); } }); }
当前错误输出
<!DOCTYPE "html"> <html lang="en"> <charset> <width> <initial-scale> <title> <h1> <p>
问题原因
- 未区分HTML标签节点和标签属性,比如meta下的charset、viewport是meta标签的属性,不是独立标签,当前逻辑把所有非JsonObject的key都作为独立标签输出,导致出现
<charset>这类错误内容 - 取值时直接调用JsonPrimitive的toString方法,会自动携带双引号,导致DOCTYPE输出变成
<!DOCTYPE "html">不符合规范 - 没有处理标签闭合逻辑,普通标签如title、h1输出内容后需要补全闭合标签
- 递归顺序错误,先处理子JsonObject再处理当前节点,导致父标签没有正确输出
- 没有处理viewport这类复合属性的拼接逻辑,无法生成正确的content属性内容
修复后代码
import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; import java.io.IOException; import java.util.Objects; // 缩进控制,可根据需要调整 private static final String INDENT = " "; private static int indentLevel = 0; private static void writeToHtmlFile(String content) throws IOException { // 原有writeToHtmlFile逻辑保留,这里加入缩进输出 // 示例实现:System.out.print(INDENT.repeat(indentLevel) + content + "\n"); } private static void convertJsonToHtml(JsonObject json) throws IOException { // 先处理根节点特殊属性 if (json.has("doctype")) { writeToHtmlFile("<!DOCTYPE " + json.get("doctype").getAsString() + ">"); json.remove("doctype"); } if (json.has("language")) { writeToHtmlFile("<html lang=\"" + json.get("language").getAsString() + "\">"); json.remove("language"); } indentLevel++; // 遍历根节点剩余标签 for (String key : json.keySet()) { parseNode(key, json.get(key)); } indentLevel--; writeToHtmlFile("</html>"); } private static void parseNode(String key, Object value) throws IOException { if (value instanceof JsonObject) { JsonObject obj = (JsonObject) value; // 处理meta类属性标签 if (Objects.equals(key, "meta")) { for (String attrKey : obj.keySet()) { if (obj.get(attrKey) instanceof JsonPrimitive) { // 普通meta属性 writeToHtmlFile("<meta " + attrKey + "=\"" + obj.get(attrKey).getAsString() + "\">"); } else if (obj.get(attrKey) instanceof JsonObject) { // 复合meta属性如viewport JsonObject attrObj = obj.get(attrKey).getAsJsonObject(); StringBuilder content = new StringBuilder(); for (String k : attrObj.keySet()) { if (content.length() > 0) content.append(", "); content.append(k).append("=").append(attrObj.get(k).getAsString()); } writeToHtmlFile("<meta name=\"" + attrKey + "\" content=\"" + content + "\">"); } } return; } // 普通标签节点,先输出开始标签 writeToHtmlFile("<" + key + ">"); indentLevel++; // 遍历子节点 for (String childKey : obj.keySet()) { parseNode(childKey, obj.get(childKey)); } indentLevel--; // 输出闭合标签 writeToHtmlFile("</" + key + ">"); } else if (value instanceof JsonPrimitive) { // 带内容的普通标签 String content = value.getAsString(); writeToHtmlFile("<" + key + ">" + content + "</" + key + ">"); } }
使用说明
将原有调用getJsonData的逻辑替换为调用convertJsonToHtml方法即可,逻辑适配当前给出的JSON结构,可根据需要扩展对JsonArray、自定义自闭合标签等场景的支持。
内容的提问来源于stack exchange,提问作者curiousQ
相关产品推荐
相关产品推荐

